[pypy-commit] pypy ppc-jit-backend: Add missing get/set interiorfield_raw operations
Author: David Schneider david.schnei...@picle.org Branch: ppc-jit-backend Changeset: r52793:d2db5350e2aa Date: 2012-02-23 01:44 -0800 http://bitbucket.org/pypy/pypy/changeset/d2db5350e2aa/ Log:Add missing get/set interiorfield_raw operations diff --git a/pypy/jit/backend/ppc/opassembler.py b/pypy/jit/backend/ppc/opassembler.py --- a/pypy/jit/backend/ppc/opassembler.py +++ b/pypy/jit/backend/ppc/opassembler.py @@ -559,6 +559,7 @@ if not we_are_translated(): signed = op.getdescr().fielddescr.is_field_signed() self._ensure_result_bit_extension(res_loc, fieldsize.value, signed) +emit_getinteriorfield_raw = emit_getinteriorfield_gc def emit_setinteriorfield_gc(self, op, arglocs, regalloc): (base_loc, index_loc, value_loc, @@ -580,7 +581,7 @@ self.mc.stbx(value_loc.value, base_loc.value, r.SCRATCH.value) else: assert 0 - +emit_setinteriorfield_raw = emit_setinteriorfield_gc class ArrayOpAssembler(object): diff --git a/pypy/jit/backend/ppc/regalloc.py b/pypy/jit/backend/ppc/regalloc.py --- a/pypy/jit/backend/ppc/regalloc.py +++ b/pypy/jit/backend/ppc/regalloc.py @@ -604,6 +604,7 @@ self.possibly_free_var(op.result) return [base_loc, index_loc, result_loc, ofs_loc, imm(ofs), imm(itemsize), imm(fieldsize)] +prepare_getinteriorfield_raw = prepare_getinteriorfield_gc def prepare_setinteriorfield_gc(self, op): t = unpack_interiorfielddescr(op.getdescr()) @@ -618,6 +619,7 @@ ofs_loc = self._ensure_value_is_boxed(ConstInt(ofs), args) return [base_loc, index_loc, value_loc, ofs_loc, imm(ofs), imm(itemsize), imm(fieldsize)] +prepare_setinteriorfield_raw = prepare_setinteriorfield_gc def prepare_arraylen_gc(self, op): arraydescr = op.getdescr() ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ppc-jit-backend: (edelsohn, bivab) fix jump conditions in malloc_cond and cond_call_gc_wb to jump on equality
Author: David Schneider david.schnei...@picle.org Branch: ppc-jit-backend Changeset: r52794:6af6f2607858 Date: 2012-02-23 01:45 -0800 http://bitbucket.org/pypy/pypy/changeset/6af6f2607858/ Log:(edelsohn, bivab) fix jump conditions in malloc_cond and cond_call_gc_wb to jump on equality diff --git a/pypy/jit/backend/ppc/opassembler.py b/pypy/jit/backend/ppc/opassembler.py --- a/pypy/jit/backend/ppc/opassembler.py +++ b/pypy/jit/backend/ppc/opassembler.py @@ -938,7 +938,7 @@ # patch the JZ above offset = self.mc.currpos() - jz_location pmc = OverwritingBuilder(self.mc, jz_location, 1) -pmc.bc(4, 2, offset) # jump if the two values are equal +pmc.bc(12, 2, offset) # jump if the two values are equal pmc.overwrite() emit_cond_call_gc_wb_array = emit_cond_call_gc_wb diff --git a/pypy/jit/backend/ppc/ppc_assembler.py b/pypy/jit/backend/ppc/ppc_assembler.py --- a/pypy/jit/backend/ppc/ppc_assembler.py +++ b/pypy/jit/backend/ppc/ppc_assembler.py @@ -343,8 +343,12 @@ # if r3 == 0 we skip the return above and jump to the exception path offset = mc.currpos() - jmp_pos pmc = OverwritingBuilder(mc, jmp_pos, 1) -pmc.bc(4, 2, offset) +pmc.bc(12, 2, offset) pmc.overwrite() +# restore the frame before leaving +mc.load(r.SCRATCH.value, r.SP.value, frame_size + ofs) +mc.mtlr(r.SCRATCH.value) +mc.addi(r.SP.value, r.SP.value, frame_size) mc.b_abs(self.propagate_exception_path) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-gc: Trying out a version of the RTyper that runs every block in its own
Author: Armin Rigo ar...@tunes.org Branch: stm-gc Changeset: r52795:df24c4bac7bc Date: 2012-02-23 11:20 +0100 http://bitbucket.org/pypy/pypy/changeset/df24c4bac7bc/ Log:Trying out a version of the RTyper that runs every block in its own transaction. diff --git a/pypy/rpython/rtyper.py b/pypy/rpython/rtyper.py --- a/pypy/rpython/rtyper.py +++ b/pypy/rpython/rtyper.py @@ -246,9 +246,12 @@ else: tracking = lambda block: None -previous_percentage = 0 -# specialize all blocks in the 'pending' list -for block in pending: +try: + import transaction +except ImportError: + previous_percentage = 0 + # specialize all blocks in the 'pending' list + for block in pending: tracking(block) blockcount += 1 self.specialize_block(block) @@ -266,6 +269,16 @@ error_report = '' self.log.event('specializing: %d / %d blocks (%d%%)%s' % (n, total, percentage, error_report)) +else: +# try a version using the transaction module +for block in pending: +transaction.add(self.specialize_block, block) +self.log.event('specializing transactionally %d blocks' % + (len(pending),)) +transaction.run() +blockcount += len(pending) +self.already_seen.update(dict.fromkeys(pending, True)) + # make sure all reprs so far have had their setup() called self.call_all_setups() ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-gc: Auto-enable the 'transaction' module if --stm is specified.
Author: Armin Rigo ar...@tunes.org Branch: stm-gc Changeset: r52796:5c8abeef1057 Date: 2012-02-23 11:30 +0100 http://bitbucket.org/pypy/pypy/changeset/5c8abeef1057/ Log:Auto-enable the 'transaction' module if --stm is specified. diff --git a/pypy/translator/goal/targetpypystandalone.py b/pypy/translator/goal/targetpypystandalone.py --- a/pypy/translator/goal/targetpypystandalone.py +++ b/pypy/translator/goal/targetpypystandalone.py @@ -185,6 +185,11 @@ # module if translation.continuation cannot be enabled config.objspace.usemodules._continuation = False +if config.translation.stm: +config.objspace.usemodules.transaction = True +elif config.objspace.usemodules.transaction: +raise Exception(use --stm, not --withmod-transaction alone) + if not config.translation.rweakref: config.objspace.usemodules._weakref = False ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-gc: Add a failing test
Author: Armin Rigo ar...@tunes.org Branch: stm-gc Changeset: r52798:64b23c237c68 Date: 2012-02-23 13:18 +0100 http://bitbucket.org/pypy/pypy/changeset/64b23c237c68/ Log:Add a failing test diff --git a/pypy/translator/stm/test/targetdemo.py b/pypy/translator/stm/test/targetdemo.py --- a/pypy/translator/stm/test/targetdemo.py +++ b/pypy/translator/stm/test/targetdemo.py @@ -63,6 +63,16 @@ print thread done. glob.done += 1 +def _check_pointer(arg1): +arg1.foobar = 40# now 'arg1' is local +return arg1 + +def check_pointer_equality(arg, retry_counter): +res = _check_pointer(arg) +if res is not arg: +debug_print(ERROR: bogus pointer equality) +raise AssertionError + def run_me(): rstm.descriptor_init() try: @@ -70,6 +80,7 @@ arg = glob._arg ll_thread.release_NOAUTO(glob.lock) arg.foobar = 41 +rstm.perform_transaction(check_pointer_equality, Arg, arg) i = 0 while i glob.LENGTH: arg.anchor = glob.anchor ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-gc: Add comment
Author: Armin Rigo ar...@tunes.org Branch: stm-gc Changeset: r52797:8b5bdb3aeda9 Date: 2012-02-23 13:18 +0100 http://bitbucket.org/pypy/pypy/changeset/8b5bdb3aeda9/ Log:Add comment diff --git a/pypy/translator/stm/test/test_transform.py b/pypy/translator/stm/test/test_transform.py --- a/pypy/translator/stm/test/test_transform.py +++ b/pypy/translator/stm/test/test_transform.py @@ -44,6 +44,7 @@ # weak test: check that there are exactly 3 stm_writebarrier inserted. # one should be for 'x.n = n', one should cover both field assignments # to the Z instance, and the 3rd one is in the block 'x.n *= 2'. +# (the latter two should be killed by the later phases.) sum = summary(graph) assert sum['stm_writebarrier'] == 3 ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-gc: Fix pointer comparison between two non-NULL objects.
Author: Armin Rigo ar...@tunes.org Branch: stm-gc Changeset: r52799:077ddb94d35b Date: 2012-02-23 13:57 +0100 http://bitbucket.org/pypy/pypy/changeset/077ddb94d35b/ Log:Fix pointer comparison between two non-NULL objects. 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 @@ -403,6 +403,7 @@ 'stm_descriptor_init':LLOp(canrun=True), 'stm_descriptor_done':LLOp(canrun=True), 'stm_writebarrier': LLOp(sideeffects=False), +'stm_normalize_global': LLOp(), 'stm_start_transaction': LLOp(canrun=True), 'stm_commit_transaction': LLOp(canrun=True), diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py --- a/pypy/rpython/memory/gc/stmgc.py +++ b/pypy/rpython/memory/gc/stmgc.py @@ -320,6 +320,11 @@ # @always_inline def stm_writebarrier(obj): +The write barrier must be called on any object that may be +a global. It looks for, and possibly makes, a local copy of +this object. The result of this call is the local copy --- +or 'obj' itself if it is already local. + if self.header(obj).tid GCFLAG_GLOBAL != 0: obj = _stm_write_barrier_global(obj) return obj @@ -380,6 +385,23 @@ stm_operations.tldict_add(obj, localobj) # return localobj +# +def stm_normalize_global(obj): +Normalize a pointer for the purpose of equality +comparison with another pointer. If 'obj' is the local +version of an existing global object, then returns the +global object. Don't use for e.g. hashing, because if 'obj' +is a purely local object, it just returns 'obj' --- which +will change at the next commit. + +if not obj: +return obj +tid = self.header(obj).tid +if tid (GCFLAG_GLOBAL|GCFLAG_WAS_COPIED) != GCFLAG_WAS_COPIED: +return obj +# the only relevant case: it's the local copy of a global object +return self.header(obj).version +self.stm_normalize_global = stm_normalize_global # -- diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py b/pypy/rpython/memory/gc/test/test_stmgc.py --- a/pypy/rpython/memory/gc/test/test_stmgc.py +++ b/pypy/rpython/memory/gc/test/test_stmgc.py @@ -564,3 +564,27 @@ s2 = llmemory.cast_adr_to_ptr(wr2.wadr, lltype.Ptr(S)) assert s2.a == 4242 assert s2 == tr1.s1 # tr1 is a root, so not copied yet + +def test_normalize_global_null(self): +a = self.gc.stm_normalize_global(llmemory.NULL) +assert a == llmemory.NULL + +def test_normalize_global_already_global(self): +sr1, sr1_adr = self.malloc(SR) +a = self.gc.stm_normalize_global(sr1_adr) +assert a == sr1_adr + +def test_normalize_global_purely_local(self): +self.select_thread(1) +sr1, sr1_adr = self.malloc(SR) +a = self.gc.stm_normalize_global(sr1_adr) +assert a == sr1_adr + +def test_normalize_global_local_copy(self): +sr1, sr1_adr = self.malloc(SR) +self.select_thread(1) +tr1_adr = self.gc.stm_writebarrier(sr1_adr) +a = self.gc.stm_normalize_global(sr1_adr) +assert a == sr1_adr +a = self.gc.stm_normalize_global(tr1_adr) +assert a == sr1_adr 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 @@ -18,6 +18,9 @@ self.stm_writebarrier_ptr = getfn( self.gcdata.gc.stm_writebarrier, [annmodel.SomeAddress()], annmodel.SomeAddress()) +self.stm_normalize_global_ptr = getfn( +self.gcdata.gc.stm_normalize_global, +[annmodel.SomeAddress()], annmodel.SomeAddress()) self.stm_start_ptr = getfn( self.gcdata.gc.start_transaction.im_func, [s_gc], annmodel.s_None) @@ -50,6 +53,15 @@ resulttype=llmemory.Address) hop.genop('cast_adr_to_ptr', [v_localadr], resultvar=op.result) +def gct_stm_normalize_global(self, hop): +op = hop.spaceop +v_adr = hop.genop('cast_ptr_to_adr', + [op.args[0]], resulttype=llmemory.Address) +v_globaladr = hop.genop(direct_call, +[self.stm_normalize_global_ptr, v_adr], +resulttype=llmemory.Address) +hop.genop('cast_adr_to_ptr', [v_globaladr], resultvar=op.result) + def gct_stm_start_transaction(self, hop): hop.genop(direct_call, [self.stm_start_ptr,
[pypy-commit] pypy stm-gc: Unifies the two detections of 'Constant' in this function.
Author: Armin Rigo ar...@tunes.org Branch: stm-gc Changeset: r52800:f4469915accd Date: 2012-02-23 14:17 +0100 http://bitbucket.org/pypy/pypy/changeset/f4469915accd/ Log:Unifies the two detections of 'Constant' in this function. diff --git a/pypy/translator/stm/localtracker.py b/pypy/translator/stm/localtracker.py --- a/pypy/translator/stm/localtracker.py +++ b/pypy/translator/stm/localtracker.py @@ -20,19 +20,17 @@ self.gsrc = GcSource(translator) def is_local(self, variable): -if isinstance(variable, Constant): -if not variable.value: # the constant NULL can be considered local -return True -self.reason = 'constant' -return False try: srcs = self.gsrc[variable] except KeyError: -# XXX we shouldn't get here, but we do translating the whole -# pypy. We should investigate at some point. In the meantime -# returning False is always safe. -self.reason = 'variable not in gsrc!' -return False +if isinstance(variable, Constant): +srcs = [variable] +else: +# XXX we shouldn't get here, but we do translating the whole +# pypy. We should investigate at some point. In the meantime +# returning False is always safe. +self.reason = 'variable not in gsrc!' +return False for src in srcs: if isinstance(src, SpaceOperation): if src.opname in RETURNS_LOCAL_POINTER: ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Test and fix: skip that test on 64-bit.
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r52801:f3469e6103b2 Date: 2012-02-23 14:42 +0100 http://bitbucket.org/pypy/pypy/changeset/f3469e6103b2/ Log:Test and fix: skip that test on 64-bit. diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -469,14 +469,16 @@ # FLOATs. if len(self._heuristic_order) len(livevars): from pypy.rlib.rarithmetic import (r_singlefloat, r_longlong, - r_ulonglong) + r_ulonglong, r_uint) added = False for var, value in livevars.items(): if var not in self._heuristic_order: -if isinstance(value, (r_longlong, r_ulonglong)): +if (r_ulonglong is not r_uint and +isinstance(value, (r_longlong, r_ulonglong))): assert 0, (should not pass a r_longlong argument for - now, because on 32-bit machines it would - need to be ordered as a FLOAT) + now, because on 32-bit machines it needs + to be ordered as a FLOAT but on 64-bit + machines as an INT) elif isinstance(value, (int, long, r_singlefloat)): kind = '1:INT' elif isinstance(value, float): 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 @@ -2,6 +2,7 @@ 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.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 @@ -178,6 +179,11 @@ myjitdriver.jit_merge_point, i1=42, r1=A(), r2=None, f1=3.5) assert got ['2:REF', '1:INT', '2:REF', '3:FLOAT'] in repr(e.value) +def test_argument_order_accept_r_uint(self): +# this used to fail on 64-bit, because r_uint == r_ulonglong +myjitdriver = JitDriver(greens=['i1'], reds=[]) +myjitdriver.jit_merge_point(i1=r_uint(42)) + class TestJITLLtype(BaseTestJIT, LLRtypeMixin): pass ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-gc: Ignore calls to collect() for now
Author: Armin Rigo ar...@tunes.org Branch: stm-gc Changeset: r52802:7326ccf9874d Date: 2012-02-23 14:00 +0100 http://bitbucket.org/pypy/pypy/changeset/7326ccf9874d/ Log:Ignore calls to collect() for now diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py --- a/pypy/rpython/memory/gc/stmgc.py +++ b/pypy/rpython/memory/gc/stmgc.py @@ -250,7 +250,8 @@ def collect(self, gen=0): -raise NotImplementedError +#raise NotImplementedError +debug_print(XXX collect() ignored) def start_transaction(self): self.collector.start_transaction() ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-gc: merge heads
Author: Armin Rigo ar...@tunes.org Branch: stm-gc Changeset: r52804:5501a1e8eba4 Date: 2012-02-23 14:59 +0100 http://bitbucket.org/pypy/pypy/changeset/5501a1e8eba4/ Log:merge heads diff --git a/pypy/translator/stm/localtracker.py b/pypy/translator/stm/localtracker.py --- a/pypy/translator/stm/localtracker.py +++ b/pypy/translator/stm/localtracker.py @@ -20,19 +20,17 @@ self.gsrc = GcSource(translator) def is_local(self, variable): -if isinstance(variable, Constant): -if not variable.value: # the constant NULL can be considered local -return True -self.reason = 'constant' -return False try: srcs = self.gsrc[variable] except KeyError: -# XXX we shouldn't get here, but we do translating the whole -# pypy. We should investigate at some point. In the meantime -# returning False is always safe. -self.reason = 'variable not in gsrc!' -return False +if isinstance(variable, Constant): +srcs = [variable] +else: +# XXX we shouldn't get here, but we do translating the whole +# pypy. We should investigate at some point. In the meantime +# returning False is always safe. +self.reason = 'variable not in gsrc!' +return False for src in srcs: if isinstance(src, SpaceOperation): if src.opname in RETURNS_LOCAL_POINTER: ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-gc: Change what is printed. Now even non-debug builds can have
Author: Armin Rigo ar...@tunes.org Branch: stm-gc Changeset: r52803:a70cb92dc2e7 Date: 2012-02-23 14:58 +0100 http://bitbucket.org/pypy/pypy/changeset/a70cb92dc2e7/ Log:Change what is printed. Now even non-debug builds can have logged the operation that caused the transaction to become inevitable. diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c --- a/pypy/translator/stm/src_stm/et.c +++ b/pypy/translator/stm/src_stm/et.c @@ -690,25 +690,19 @@ if (d == NULL) return; + if (is_inevitable(d)) /* also when the transaction is inactive */ +{ + return; /* I am already inevitable */ +} + #ifdef RPY_STM_DEBUG_PRINT PYPY_DEBUG_START(stm-inevitable); -# ifdef RPY_STM_ASSERT if (PYPY_HAVE_DEBUG_PRINTS) { - fprintf(PYPY_DEBUG_FILE, %s%s\n, why, - is_inevitable(d) ? : ); + fprintf(PYPY_DEBUG_FILE, %s\n, why); } -# endif #endif - if (is_inevitable(d)) /* also when the transaction is inactive */ -{ -#ifdef RPY_STM_DEBUG_PRINT - PYPY_DEBUG_STOP(stm-inevitable); -#endif - return; /* I am already inevitable */ -} - while (1) { unsigned long curtime = get_global_timestamp(d); diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h --- a/pypy/translator/stm/src_stm/et.h +++ b/pypy/translator/stm/src_stm/et.h @@ -30,7 +30,7 @@ float stm_read_int4f(void *, long); -#ifdef RPY_STM_ASSERT +#if 1 /* #ifdef RPY_STM_ASSERT --- but it's always useful to have this info */ # define STM_CCHARP1(arg)char* arg # define STM_EXPLAIN1(info) info #else ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: refactor the autoflush of streams: we cannot keep a set of w_iobase instances, else they would be never collected by the GC. Instead, we keep a set of 'holders', which have
Author: Antonio Cuni anto.c...@gmail.com Branch: Changeset: r52807:4867e38be6fb Date: 2012-02-23 16:11 +0100 http://bitbucket.org/pypy/pypy/changeset/4867e38be6fb/ Log:refactor the autoflush of streams: we cannot keep a set of w_iobase instances, else they would be never collected by the GC. Instead, we keep a set of 'holders', which have a weakref to the actual stream. When the stream is closed, the holder is removed from the set diff --git a/pypy/module/_io/__init__.py b/pypy/module/_io/__init__.py --- a/pypy/module/_io/__init__.py +++ b/pypy/module/_io/__init__.py @@ -39,5 +39,6 @@ def shutdown(self, space): # at shutdown, flush all open streams. Ignore I/O errors. -from pypy.module._io.interp_iobase import flush_all_streams -flush_all_streams(space) +from pypy.module._io.interp_iobase import get_autoflushher +get_autoflushher(space).flush_all(space) + 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 @@ -5,6 +5,8 @@ from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rlib.rstring import StringBuilder +from pypy.rlib import rweakref + DEFAULT_BUFFER_SIZE = 8192 @@ -43,7 +45,8 @@ self.space = space self.w_dict = space.newdict() self.__IOBase_closed = False -register_flushable_stream(space, self) +self.streamholder = None # needed by AutoFlusher +get_autoflushher(space).add(self) def getdict(self, space): return self.w_dict @@ -99,8 +102,7 @@ space.call_method(self, flush) finally: self.__IOBase_closed = True -flushable_streams = get_flushable_streams(space) -del flushable_streams[self] +get_autoflushher(space).remove(self) def flush_w(self, space): if self._CLOSED(): @@ -312,26 +314,46 @@ # functions to make sure that all streams are flushed on exit # -class IoState: +class StreamHolder(object): + +def __init__(self, w_iobase): +self.w_iobase_ref = rweakref.ref(w_iobase) +w_iobase.autoflusher = self + +def autoflush(self, space): +w_iobase = self.w_iobase_ref() +if w_iobase is not None: +space.call_method(w_iobase, 'flush') # XXX: ignore IOErrors? + + +class AutoFlusher(object): + def __init__(self, space): -self.flushable_streams = {} +self.streams = {} -def get_flushable_streams(space): -return space.fromcache(IoState).flushable_streams +def add(self, w_iobase): +assert w_iobase.streamholder is None +holder = StreamHolder(w_iobase) +w_iobase.streamholder = holder +self.streams[holder] = None -def register_flushable_stream(space, w_stream): -streams = get_flushable_streams(space) -streams[w_stream] = None +def remove(self, w_iobase): +holder = w_iobase.streamholder +if holder is not None: +del self.streams[holder] -def flush_all_streams(space): -flushable_streams = get_flushable_streams(space) -while flushable_streams: -for w_stream in flushable_streams.keys(): -assert isinstance(w_stream, W_IOBase) -try: -del flushable_streams[w_stream] -except KeyError: -pass# key was removed in the meantime -else: -space.call_method(w_stream, 'flush') # XXX: ignore IOErrors? - +def flush_all(self, space): +while self.streams: +for streamholder in self.streams.keys(): +try: +del self.streams[streamholder] +except KeyError: +pass# key was removed in the meantime +else: +streamholder.autoflush(space) + + +def get_autoflushher(space): +return space.fromcache(AutoFlusher) + + ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: make sure to flush all _io streams when we exit the interpreter
Author: Antonio Cuni anto.c...@gmail.com Branch: Changeset: r52806:d4dee87e47cc Date: 2012-02-23 12:06 +0100 http://bitbucket.org/pypy/pypy/changeset/d4dee87e47cc/ Log:make sure to flush all _io streams when we exit the interpreter diff --git a/pypy/module/_io/__init__.py b/pypy/module/_io/__init__.py --- a/pypy/module/_io/__init__.py +++ b/pypy/module/_io/__init__.py @@ -28,6 +28,7 @@ } def init(self, space): +MixedModule.init(self, space) w_UnsupportedOperation = space.call_function( space.w_type, space.wrap('UnsupportedOperation'), @@ -35,3 +36,8 @@ space.newdict()) space.setattr(self, space.wrap('UnsupportedOperation'), w_UnsupportedOperation) + +def shutdown(self, space): +# at shutdown, flush all open streams. Ignore I/O errors. +from pypy.module._io.interp_iobase import flush_all_streams +flush_all_streams(space) 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 @@ -43,6 +43,7 @@ self.space = space self.w_dict = space.newdict() self.__IOBase_closed = False +register_flushable_stream(space, self) def getdict(self, space): return self.w_dict @@ -98,6 +99,8 @@ space.call_method(self, flush) finally: self.__IOBase_closed = True +flushable_streams = get_flushable_streams(space) +del flushable_streams[self] def flush_w(self, space): if self._CLOSED(): @@ -303,3 +306,32 @@ read = interp2app(W_RawIOBase.read_w), readall = interp2app(W_RawIOBase.readall_w), ) + + +# +# functions to make sure that all streams are flushed on exit +# + +class IoState: +def __init__(self, space): +self.flushable_streams = {} + +def get_flushable_streams(space): +return space.fromcache(IoState).flushable_streams + +def register_flushable_stream(space, w_stream): +streams = get_flushable_streams(space) +streams[w_stream] = None + +def flush_all_streams(space): +flushable_streams = get_flushable_streams(space) +while flushable_streams: +for w_stream in flushable_streams.keys(): +assert isinstance(w_stream, W_IOBase) +try: +del flushable_streams[w_stream] +except KeyError: +pass# key was removed in the meantime +else: +space.call_method(w_stream, 'flush') # XXX: ignore IOErrors? + 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 @@ -160,3 +160,20 @@ f.close() assert repr(f) == _io.FileIO [closed] +def test_flush_at_exit(): +from pypy import conftest +from pypy.tool.option import make_config, make_objspace +from pypy.tool.udir import udir + +tmpfile = udir.join('test_flush_at_exit') +config = make_config(conftest.option) +space = make_objspace(config) +space.appexec([space.wrap(str(tmpfile))], (tmpfile): +import io +f = io.open(tmpfile, 'w') +f.write('42') +# no flush() and no close() +import sys; sys._keepalivesomewhereobscure = f +) +space.finish() +assert tmpfile.read() == '42' ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fixes. Sorry.
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r52811:9ba62b41a086 Date: 2012-02-23 18:28 +0100 http://bitbucket.org/pypy/pypy/changeset/9ba62b41a086/ Log:Fixes. Sorry. diff --git a/pypy/jit/backend/x86/test/test_ztranslation.py b/pypy/jit/backend/x86/test/test_ztranslation.py --- a/pypy/jit/backend/x86/test/test_ztranslation.py +++ b/pypy/jit/backend/x86/test/test_ztranslation.py @@ -52,6 +52,7 @@ set_param(jitdriver, trace_eagerness, 2) total = 0 frame = Frame(i) +j = float(j) while frame.i 3: jitdriver.can_enter_jit(frame=frame, total=total, j=j) jitdriver.jit_merge_point(frame=frame, total=total, j=j) 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 @@ -2943,11 +2943,18 @@ self.check_resops(arraylen_gc=3) def test_ulonglong_mod(self): -myjitdriver = JitDriver(greens = [], reds = ['n', 'sa', 'i']) +myjitdriver = JitDriver(greens = [], reds = ['n', 'a']) +class A: +pass def f(n): sa = i = rffi.cast(rffi.ULONGLONG, 1) +a = A() while i rffi.cast(rffi.ULONGLONG, n): -myjitdriver.jit_merge_point(sa=sa, n=n, i=i) +a.sa = sa +a.i = i +myjitdriver.jit_merge_point(n=n, a=a) +sa = a.sa +i = a.i sa += sa % i i += 1 res = self.meta_interp(f, [32]) diff --git a/pypy/jit/tl/tinyframe/tinyframe.py b/pypy/jit/tl/tinyframe/tinyframe.py --- a/pypy/jit/tl/tinyframe/tinyframe.py +++ b/pypy/jit/tl/tinyframe/tinyframe.py @@ -210,7 +210,7 @@ def repr(self): return function %s(%s) % (self.outer.repr(), self.inner.repr()) -driver = JitDriver(greens = ['code', 'i'], reds = ['self'], +driver = JitDriver(greens = ['i', 'code'], reds = ['self'], virtualizables = ['self']) class Frame(object): ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix this test
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r52813:55fd1d7090fb Date: 2012-02-23 18:32 +0100 http://bitbucket.org/pypy/pypy/changeset/55fd1d7090fb/ Log:Fix this test 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 @@ -145,9 +145,9 @@ g = pipe.stdin f = pipe.stdout expect(f, g, ll_os.ll_os_getenv, (PYPY_GENERATIONGC_NURSERY,), None) -if sys.platform.startswith('linux'): # on Mac, uses another (sandboxsafe) approach -expect(f, g, ll_os.ll_os_open, (/proc/cpuinfo, 0, 420), - OSError(5232, xyz)) +#if sys.platform.startswith('linux'): +#expect(f, g, ll_os.ll_os_open, (/proc/cpuinfo, 0, 420), +# OSError(5232, xyz)) expect(f, g, ll_os.ll_os_getenv, (PYPY_GC_DEBUG,), None) g.close() tail = f.read() ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix.
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r52812:b8aed975987f Date: 2012-02-23 18:30 +0100 http://bitbucket.org/pypy/pypy/changeset/b8aed975987f/ Log:Fix. diff --git a/pypy/rlib/debug.py b/pypy/rlib/debug.py --- a/pypy/rlib/debug.py +++ b/pypy/rlib/debug.py @@ -26,6 +26,7 @@ llop.debug_print_traceback(lltype.Void) llop.debug_fatalerror(lltype.Void, msg) fatalerror._dont_inline_ = True +fatalerror._jit_look_inside_ = False fatalerror._annenforceargs_ = [str] def fatalerror_notb(msg): @@ -34,6 +35,7 @@ from pypy.rpython.lltypesystem.lloperation import llop llop.debug_fatalerror(lltype.Void, msg) fatalerror_notb._dont_inline_ = True +fatalerror_notb._jit_look_inside_ = False fatalerror_notb._annenforceargs_ = [str] ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: cpyext: add pymath.h and a definition of Py_HUGE_VAL.
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: Changeset: r52814:13ea80daa6d4 Date: 2012-02-23 00:07 +0100 http://bitbucket.org/pypy/pypy/changeset/13ea80daa6d4/ Log:cpyext: add pymath.h and a definition of Py_HUGE_VAL. diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h --- a/pypy/module/cpyext/include/Python.h +++ b/pypy/module/cpyext/include/Python.h @@ -113,6 +113,7 @@ #include compile.h #include frameobject.h #include eval.h +#include pymath.h #include pymem.h #include pycobject.h #include pycapsule.h diff --git a/pypy/module/cpyext/include/pymath.h b/pypy/module/cpyext/include/pymath.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/pymath.h @@ -0,0 +1,20 @@ +#ifndef Py_PYMATH_H +#define Py_PYMATH_H + +/** +Symbols and macros to supply platform-independent interfaces to mathematical +functions and constants +**/ + +/* HUGE_VAL is supposed to expand to a positive double infinity. Python + * uses Py_HUGE_VAL instead because some platforms are broken in this + * respect. We used to embed code in pyport.h to try to worm around that, + * but different platforms are broken in conflicting ways. If you're on + * a platform where HUGE_VAL is defined incorrectly, fiddle your Python + * config to #define Py_HUGE_VAL to something that works on your platform. + */ +#ifndef Py_HUGE_VAL +#define Py_HUGE_VAL HUGE_VAL +#endif + +#endif /* Py_PYMATH_H */ ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: cpyext: implement PyUnicode_Tailmatch
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: Changeset: r52815:db6f7731ed5f Date: 2012-02-23 00:19 +0100 http://bitbucket.org/pypy/pypy/changeset/db6f7731ed5f/ Log:cpyext: implement PyUnicode_Tailmatch 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 @@ -2317,17 +2317,6 @@ use the default error handling. raise NotImplementedError -@cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real], rffi.INT_real, error=-1) -def PyUnicode_Tailmatch(space, str, substr, start, end, direction): -Return 1 if substr matches str*[*start:end] at the given tail end -(direction == -1 means to do a prefix match, direction == 1 a suffix match), -0 otherwise. Return -1 if an error occurred. - -This function used an int type for start and end. This -might require changes in your code for properly supporting 64-bit -systems. -raise NotImplementedError - @cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real], Py_ssize_t, error=-2) def PyUnicode_Find(space, str, substr, start, end, direction): Return the first position of substr in str*[*start:end] using the given diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py --- a/pypy/module/cpyext/test/test_unicodeobject.py +++ b/pypy/module/cpyext/test/test_unicodeobject.py @@ -437,3 +437,10 @@ api.PyUnicode_Replace(w_str, w_substr, w_replstr, 2)) assert uzbzbzbzb == space.unwrap( api.PyUnicode_Replace(w_str, w_substr, w_replstr, -1)) + +def test_tailmatch(self, space, api): +w_str = space.wrap(uabcdef) +assert api.PyUnicode_Tailmatch(w_str, space.wrap(cde), 2, 10, 1) == 1 +assert api.PyUnicode_Tailmatch(w_str, space.wrap(cde), 1, 5, -1) == 1 +self.raises(space, api, TypeError, +api.PyUnicode_Tailmatch, w_str, space.wrap(3), 2, 10, 1) diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -12,7 +12,7 @@ make_typedescr, get_typedescr) from pypy.module.cpyext.stringobject import PyString_Check from pypy.module.sys.interp_encoding import setdefaultencoding -from pypy.objspace.std import unicodeobject, unicodetype +from pypy.objspace.std import unicodeobject, unicodetype, stringtype from pypy.rlib import runicode from pypy.tool.sourcetools import func_renamer import sys @@ -560,3 +560,16 @@ return space.call_method(w_str, replace, w_substr, w_replstr, space.wrap(maxcount)) +@cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real], + rffi.INT_real, error=-1) +def PyUnicode_Tailmatch(space, w_str, w_substr, start, end, direction): +Return 1 if substr matches str[start:end] at the given tail end +(direction == -1 means to do a prefix match, direction == 1 a +suffix match), 0 otherwise. Return -1 if an error occurred. +str = space.unicode_w(w_str) +substr = space.unicode_w(w_substr) +if rffi.cast(lltype.Signed, direction) = 0: +return stringtype.stringstartswith(str, substr, start, end) +else: +return stringtype.stringendswith(str, substr, start, end) + ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: cpyext: add PyUnicode_GetMax()
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: Changeset: r52817:16b015b252c3 Date: 2012-02-23 00:25 +0100 http://bitbucket.org/pypy/pypy/changeset/16b015b252c3/ Log:cpyext: add PyUnicode_GetMax() diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -155,6 +155,11 @@ except KeyError: return -1.0 +@cpython_api([], Py_UNICODE, error=CANNOT_FAIL) +def PyUnicode_GetMax(space): +Get the maximum ordinal for a Unicode character. +return unichr(runicode.MAXUNICODE) + @cpython_api([PyObject], rffi.CCHARP, error=CANNOT_FAIL) def PyUnicode_AS_DATA(space, ref): Return a pointer to the internal buffer of the object. o has to be a ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: cpyext: implement remaining Py_UNICODE_IS* functions
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: Changeset: r52818:4f01039bfe04 Date: 2012-02-23 00:38 +0100 http://bitbucket.org/pypy/pypy/changeset/4f01039bfe04/ Log:cpyext: implement remaining Py_UNICODE_IS* functions 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 @@ -1853,26 +1853,6 @@ raise NotImplementedError -@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) -def Py_UNICODE_ISTITLE(space, ch): -Return 1 or 0 depending on whether ch is a titlecase character. -raise NotImplementedError - -@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) -def Py_UNICODE_ISDIGIT(space, ch): -Return 1 or 0 depending on whether ch is a digit character. -raise NotImplementedError - -@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) -def Py_UNICODE_ISNUMERIC(space, ch): -Return 1 or 0 depending on whether ch is a numeric character. -raise NotImplementedError - -@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) -def Py_UNICODE_ISALPHA(space, ch): -Return 1 or 0 depending on whether ch is an alphabetic character. -raise NotImplementedError - @cpython_api([rffi.CCHARP], PyObject) def PyUnicode_FromFormat(space, format): Take a C printf()-style format string and a variable number of diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py --- a/pypy/module/cpyext/test/test_unicodeobject.py +++ b/pypy/module/cpyext/test/test_unicodeobject.py @@ -204,8 +204,18 @@ assert api.Py_UNICODE_ISSPACE(unichr(char)) assert not api.Py_UNICODE_ISSPACE(u'a') +assert api.Py_UNICODE_ISALPHA(u'a') +assert not api.Py_UNICODE_ISALPHA(u'0') +assert api.Py_UNICODE_ISALNUM(u'a') +assert api.Py_UNICODE_ISALNUM(u'0') +assert not api.Py_UNICODE_ISALNUM(u'+') + assert api.Py_UNICODE_ISDECIMAL(u'\u0660') assert not api.Py_UNICODE_ISDECIMAL(u'a') +assert api.Py_UNICODE_ISDIGIT(u'9') +assert not api.Py_UNICODE_ISDIGIT(u'@') +assert api.Py_UNICODE_ISNUMERIC(u'9') +assert not api.Py_UNICODE_ISNUMERIC(u'@') for char in [0x0a, 0x0d, 0x1c, 0x1d, 0x1e, 0x85, 0x2028, 0x2029]: assert api.Py_UNICODE_ISLINEBREAK(unichr(char)) @@ -216,6 +226,9 @@ assert not api.Py_UNICODE_ISUPPER(u'a') assert not api.Py_UNICODE_ISLOWER(u'#65533;') assert api.Py_UNICODE_ISUPPER(u'#65533;') +assert not api.Py_UNICODE_ISTITLE(u'A') +assert api.Py_UNICODE_ISTITLE( +u'\N{LATIN CAPITAL LETTER L WITH SMALL LETTER J}') def test_TOLOWER(self, space, api): assert api.Py_UNICODE_TOLOWER(u'#65533;') == u'#65533;' diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -89,6 +89,11 @@ return unicodedb.isspace(ord(ch)) @cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) +def Py_UNICODE_ISALPHA(space, ch): +Return 1 or 0 depending on whether ch is an alphabetic character. +return unicodedb.isalpha(ord(ch)) + +@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) def Py_UNICODE_ISALNUM(space, ch): Return 1 or 0 depending on whether ch is an alphanumeric character. return unicodedb.isalnum(ord(ch)) @@ -104,6 +109,16 @@ return unicodedb.isdecimal(ord(ch)) @cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) +def Py_UNICODE_ISDIGIT(space, ch): +Return 1 or 0 depending on whether ch is a digit character. +return unicodedb.isdigit(ord(ch)) + +@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) +def Py_UNICODE_ISNUMERIC(space, ch): +Return 1 or 0 depending on whether ch is a numeric character. +return unicodedb.isnumeric(ord(ch)) + +@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) def Py_UNICODE_ISLOWER(space, ch): Return 1 or 0 depending on whether ch is a lowercase character. return unicodedb.islower(ord(ch)) @@ -113,6 +128,11 @@ Return 1 or 0 depending on whether ch is an uppercase character. return unicodedb.isupper(ord(ch)) +@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) +def Py_UNICODE_ISTITLE(space, ch): +Return 1 or 0 depending on whether ch is a titlecase character. +return unicodedb.istitle(ord(ch)) + @cpython_api([Py_UNICODE], Py_UNICODE, error=CANNOT_FAIL) def Py_UNICODE_TOLOWER(space, ch): Return the character ch converted to lower case. ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: cpyext: implement PyRun_StringFlags()
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: Changeset: r52821:91960d426061 Date: 2012-02-23 01:37 +0100 http://bitbucket.org/pypy/pypy/changeset/91960d426061/ Log:cpyext: implement PyRun_StringFlags() diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py --- a/pypy/module/cpyext/eval.py +++ b/pypy/module/cpyext/eval.py @@ -9,7 +9,7 @@ from pypy.module.__builtin__ import compiling PyCompilerFlags = cpython_struct( -PyCompilerFlags, ()) +PyCompilerFlags, ((cf_flags, rffi.INT),)) PyCompilerFlagsPtr = lltype.Ptr(PyCompilerFlags) @cpython_api([PyObject, PyObject, PyObject], PyObject) @@ -86,7 +86,7 @@ Py_file_input = 257 Py_eval_input = 258 -def compile_string(space, source, filename, start): +def compile_string(space, source, filename, start, flags=0): w_source = space.wrap(source) start = rffi.cast(lltype.Signed, start) if start == Py_file_input: @@ -98,7 +98,7 @@ else: raise OperationError(space.w_ValueError, space.wrap( invalid mode parameter for compilation)) -return compiling.compile(space, w_source, filename, mode) +return compiling.compile(space, w_source, filename, mode, flags) def run_string(space, source, filename, start, w_globals, w_locals): w_code = compile_string(space, source, filename, start) @@ -121,6 +121,23 @@ filename = string return run_string(space, source, filename, start, w_globals, w_locals) +@cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject, + PyCompilerFlagsPtr], PyObject) +def PyRun_StringFlags(space, source, start, w_globals, w_locals, flagsptr): +Execute Python source code from str in the context specified by the +dictionaries globals and locals with the compiler flags specified by +flags. The parameter start specifies the start token that should be used to +parse the source code. + +Returns the result of executing the code as a Python object, or NULL if an +exception was raised. +if flagsptr: +flags = flagsptr.c_cf_flags +else: +flags = 0 +w_code = compile_string(space, source, string, start, flags) +return compiling.eval(space, w_code, w_globals, w_locals) + @cpython_api([FILEP, CONST_STRING, rffi.INT_real, PyObject, PyObject], PyObject) def PyRun_File(space, fp, filename, start, w_globals, w_locals): This is a simplified interface to PyRun_FileExFlags() below, leaving @@ -162,7 +179,7 @@ @cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real, PyCompilerFlagsPtr], PyObject) -def Py_CompileStringFlags(space, source, filename, start, flags): +def Py_CompileStringFlags(space, source, filename, start, flagsptr): Parse and compile the Python source code in str, returning the resulting code object. The start token is given by start; this can be used to constrain the code which can be compiled and should @@ -172,7 +189,8 @@ returns NULL if the code cannot be parsed or compiled. source = rffi.charp2str(source) filename = rffi.charp2str(filename) -if flags: -raise OperationError(space.w_NotImplementedError, space.wrap( -cpyext Py_CompileStringFlags does not accept flags)) -return compile_string(space, source, filename, start) +if flagsptr: +flags = flagsptr.c_cf_flags +else: +flags = 0 +return compile_string(space, source, filename, start, flags) diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h --- a/pypy/module/cpyext/include/pythonrun.h +++ b/pypy/module/cpyext/include/pythonrun.h @@ -19,6 +19,8 @@ int cf_flags; /* bitmask of CO_xxx flags relevant to future */ } PyCompilerFlags; +#define PyCF_SOURCE_IS_UTF8 0x0100 + #define Py_CompileString(str, filename, start) Py_CompileStringFlags(str, filename, start, NULL) #ifdef __cplusplus 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 @@ -2483,17 +2483,6 @@ source code is read from fp instead of an in-memory string. raise NotImplementedError -@cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject, PyCompilerFlags], PyObject) -def PyRun_StringFlags(space, str, start, globals, locals, flags): -Execute Python source code from str in the context specified by the -dictionaries globals and locals with the compiler flags specified by -flags. The parameter start specifies the start token that should be used to -parse the source code. - -Returns the result of executing the code as a Python object, or NULL if an -exception was raised. -raise NotImplementedError - @cpython_api([FILE, rffi.CCHARP, rffi.INT_real, PyObject, PyObject, rffi.INT_real], PyObject) def PyRun_FileEx(space, fp, filename, start, globals, locals, closeit): This is a simplified interface to PyRun_FileExFlags() below, leaving diff --git
[pypy-commit] pypy default: cpyext: Implement PyEval_MergeCompilerFlags()
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: Changeset: r52822:116c15429aa4 Date: 2012-02-23 02:05 +0100 http://bitbucket.org/pypy/pypy/changeset/116c15429aa4/ Log:cpyext: Implement PyEval_MergeCompilerFlags() diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py --- a/pypy/module/cpyext/eval.py +++ b/pypy/module/cpyext/eval.py @@ -1,4 +1,5 @@ from pypy.interpreter.error import OperationError +from pypy.interpreter.astcompiler import consts from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, fread, feof, Py_ssize_tP, @@ -12,6 +13,12 @@ PyCompilerFlags, ((cf_flags, rffi.INT),)) PyCompilerFlagsPtr = lltype.Ptr(PyCompilerFlags) +PyCF_MASK = (consts.CO_FUTURE_DIVISION | + consts.CO_FUTURE_ABSOLUTE_IMPORT | + consts.CO_FUTURE_WITH_STATEMENT | + consts.CO_FUTURE_PRINT_FUNCTION | + consts.CO_FUTURE_UNICODE_LITERALS) + @cpython_api([PyObject, PyObject, PyObject], PyObject) def PyEval_CallObjectWithKeywords(space, w_obj, w_arg, w_kwds): return space.call(w_obj, w_arg, w_kwds) @@ -194,3 +201,23 @@ else: flags = 0 return compile_string(space, source, filename, start, flags) + +@cpython_api([PyCompilerFlagsPtr], rffi.INT_real, error=CANNOT_FAIL) +def PyEval_MergeCompilerFlags(space, cf): +This function changes the flags of the current evaluation +frame, and returns true on success, false on failure. +result = cf.c_cf_flags != 0 +current_frame = space.getexecutioncontext().gettopframe_nohidden() +if current_frame: +codeflags = current_frame.pycode.co_flags +compilerflags = codeflags PyCF_MASK +if compilerflags: +result = 1; +cf.c_cf_flags |= compilerflags +# No future keyword at the moment +# if codeflags CO_GENERATOR_ALLOWED: +# result = 1 +# cf.c_cf_flags |= CO_GENERATOR_ALLOWED +return result + + diff --git a/pypy/module/cpyext/include/code.h b/pypy/module/cpyext/include/code.h --- a/pypy/module/cpyext/include/code.h +++ b/pypy/module/cpyext/include/code.h @@ -13,13 +13,19 @@ /* Masks for co_flags above */ /* These values are also in funcobject.py */ -#define CO_OPTIMIZED 0x0001 -#define CO_NEWLOCALS 0x0002 -#define CO_VARARGS 0x0004 -#define CO_VARKEYWORDS 0x0008 +#define CO_OPTIMIZED0x0001 +#define CO_NEWLOCALS0x0002 +#define CO_VARARGS 0x0004 +#define CO_VARKEYWORDS 0x0008 #define CO_NESTED 0x0010 #define CO_GENERATOR0x0020 +#define CO_FUTURE_DIVISION 0x02000 +#define CO_FUTURE_ABSOLUTE_IMPORT 0x04000 +#define CO_FUTURE_WITH_STATEMENT 0x08000 +#define CO_FUTURE_PRINT_FUNCTION 0x1 +#define CO_FUTURE_UNICODE_LITERALS 0x2 + #ifdef __cplusplus } #endif diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h --- a/pypy/module/cpyext/include/pythonrun.h +++ b/pypy/module/cpyext/include/pythonrun.h @@ -19,7 +19,13 @@ int cf_flags; /* bitmask of CO_xxx flags relevant to future */ } PyCompilerFlags; +#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ + CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ + CO_FUTURE_UNICODE_LITERALS) +#define PyCF_MASK_OBSOLETE (CO_NESTED) #define PyCF_SOURCE_IS_UTF8 0x0100 +#define PyCF_DONT_IMPLY_DEDENT 0x0200 +#define PyCF_ONLY_AST 0x0400 #define Py_CompileString(str, filename, start) Py_CompileStringFlags(str, filename, start, NULL) diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py --- a/pypy/module/cpyext/stubs.py +++ b/pypy/module/cpyext/stubs.py @@ -2527,12 +2527,6 @@ throw() methods of generator objects. raise NotImplementedError -@cpython_api([PyCompilerFlags], rffi.INT_real, error=CANNOT_FAIL) -def PyEval_MergeCompilerFlags(space, cf): -This function changes the flags of the current evaluation frame, and returns -true on success, false on failure. -raise NotImplementedError - @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyWeakref_Check(space, ob): Return true if ob is either a reference or proxy object. diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py --- a/pypy/module/cpyext/test/test_eval.py +++ b/pypy/module/cpyext/test/test_eval.py @@ -283,3 +283,21 @@ print dir(mod) print mod.__dict__ assert mod.f(42) == 47 + +def test_merge_compiler_flags(self): +module = self.import_extension('foo', [ +(get_flags, METH_NOARGS, + +PyCompilerFlags flags; +flags.cf_flags = 0; +int result = PyEval_MergeCompilerFlags(flags); +return Py_BuildValue(ii, result, flags.cf_flags); + ), +]) +assert module.get_flags() == (0, 0) + +
[pypy-commit] pypy default: cpyext: add PyCode_Check(), PyCode_GetNumFree()
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: Changeset: r52819:6cc0977ede36 Date: 2012-02-23 00:50 +0100 http://bitbucket.org/pypy/pypy/changeset/6cc0977ede36/ Log:cpyext: add PyCode_Check(), 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, +PyObjectFields, generic_cpy_call, CONST_STRING, CANNOT_FAIL, 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) @@ -48,6 +48,7 @@ PyFunction_Check, PyFunction_CheckExact = build_type_checkers(Function, Function) PyMethod_Check, PyMethod_CheckExact = build_type_checkers(Method, Method) +PyCode_Check, PyCode_CheckExact = build_type_checkers(Code, PyCode) def function_attach(space, py_obj, w_obj): py_func = rffi.cast(PyFunctionObject, py_obj) @@ -167,3 +168,9 @@ freevars=[], cellvars=[])) +@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyCode_GetNumFree(space, w_co): +Return the number of free variables in co. +co = space.interp_w(PyCode, w_co) +return len(co.co_freevars) + 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 @@ -182,16 +182,6 @@ used as the positional and keyword parameters to the object's constructor. raise NotImplementedError -@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) -def PyCode_Check(space, co): -Return true if co is a code object -raise NotImplementedError - -@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) -def PyCode_GetNumFree(space, co): -Return the number of free variables in co. -raise NotImplementedError - @cpython_api([PyObject], rffi.INT_real, error=-1) def PyCodec_Register(space, search_function): Register a new codec search function. diff --git a/pypy/module/cpyext/test/test_funcobject.py b/pypy/module/cpyext/test/test_funcobject.py --- a/pypy/module/cpyext/test/test_funcobject.py +++ b/pypy/module/cpyext/test/test_funcobject.py @@ -81,6 +81,14 @@ rffi.free_charp(filename) rffi.free_charp(funcname) +def test_getnumfree(self, space, api): +w_function = space.appexec([], (): +a = 5 +def method(x): return a, x +return method +) +assert api.PyCode_GetNumFree(w_function.code) == 1 + def test_classmethod(self, space, api): w_function = space.appexec([], (): def method(x): return x ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: cpyext: add PyEval_EvalCode()
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: Changeset: r52820:33f342e61049 Date: 2012-02-23 01:05 +0100 http://bitbucket.org/pypy/pypy/changeset/33f342e61049/ Log:cpyext: add PyEval_EvalCode() diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py --- a/pypy/module/cpyext/eval.py +++ b/pypy/module/cpyext/eval.py @@ -5,6 +5,7 @@ cpython_struct) from pypy.module.cpyext.pyobject import PyObject, borrow_from from pypy.module.cpyext.pyerrors import PyErr_SetFromErrno +from pypy.module.cpyext.funcobject import PyCodeObject from pypy.module.__builtin__ import compiling PyCompilerFlags = cpython_struct( @@ -48,6 +49,17 @@ return None return borrow_from(None, caller.w_globals) +@cpython_api([PyCodeObject, PyObject, PyObject], PyObject) +def PyEval_EvalCode(space, w_code, w_globals, w_locals): +This is a simplified interface to PyEval_EvalCodeEx(), with just +the code object, and the dictionaries of global and local variables. +The other arguments are set to NULL. +if w_globals is None: +w_globals = space.w_None +if w_locals is None: +w_locals = space.w_None +return compiling.eval(space, w_code, w_globals, w_locals) + @cpython_api([PyObject, PyObject], PyObject) def PyObject_CallObject(space, w_obj, w_arg): 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 @@ -2514,13 +2514,6 @@ returns. raise NotImplementedError -@cpython_api([PyCodeObject, PyObject, PyObject], PyObject) -def PyEval_EvalCode(space, co, globals, locals): -This is a simplified interface to PyEval_EvalCodeEx(), with just -the code object, and the dictionaries of global and local variables. -The other arguments are set to NULL. -raise NotImplementedError - @cpython_api([PyCodeObject, PyObject, PyObject, PyObjectP, rffi.INT_real, PyObjectP, rffi.INT_real, PyObjectP, rffi.INT_real, PyObject], PyObject) def PyEval_EvalCodeEx(space, co, globals, locals, args, argcount, kws, kwcount, defs, defcount, closure): Evaluate a precompiled code object, given a particular environment for its diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py --- a/pypy/module/cpyext/test/test_eval.py +++ b/pypy/module/cpyext/test/test_eval.py @@ -63,6 +63,22 @@ assert space.int_w(w_res) == 10 +def test_evalcode(self, space, api): +w_f = space.appexec([], (): +def f(*args): +assert isinstance(args, tuple) +return len(args) + 8 +return f +) + +w_t = space.newtuple([space.wrap(1), space.wrap(2)]) +w_globals = space.newdict() +w_locals = space.newdict() +space.setitem(w_locals, space.wrap(args), w_t) +w_res = api.PyEval_EvalCode(w_f.code, w_globals, w_locals) + +assert space.int_w(w_res) == 10 + def test_run_simple_string(self, space, api): def run(code): buf = rffi.str2charp(code) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Translation fixes
Author: Amaury Forgeot d'Arc amaur...@gmail.com Branch: Changeset: r52823:f50a42098ae3 Date: 2012-02-23 16:02 +0100 http://bitbucket.org/pypy/pypy/changeset/f50a42098ae3/ Log:Translation fixes diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py --- a/pypy/module/cpyext/eval.py +++ b/pypy/module/cpyext/eval.py @@ -138,8 +138,9 @@ Returns the result of executing the code as a Python object, or NULL if an exception was raised. +source = rffi.charp2str(source) if flagsptr: -flags = flagsptr.c_cf_flags +flags = rffi.cast(lltype.Signed, flagsptr.c_cf_flags) else: flags = 0 w_code = compile_string(space, source, string, start, flags) @@ -197,7 +198,7 @@ source = rffi.charp2str(source) filename = rffi.charp2str(filename) if flagsptr: -flags = flagsptr.c_cf_flags +flags = rffi.cast(lltype.Signed, flagsptr.c_cf_flags) else: flags = 0 return compile_string(space, source, filename, start, flags) @@ -206,18 +207,20 @@ def PyEval_MergeCompilerFlags(space, cf): This function changes the flags of the current evaluation frame, and returns true on success, false on failure. -result = cf.c_cf_flags != 0 +flags = rffi.cast(lltype.Signed, cf.c_cf_flags) +result = flags != 0 current_frame = space.getexecutioncontext().gettopframe_nohidden() if current_frame: codeflags = current_frame.pycode.co_flags compilerflags = codeflags PyCF_MASK if compilerflags: -result = 1; -cf.c_cf_flags |= compilerflags +result = 1 +flags |= compilerflags # No future keyword at the moment # if codeflags CO_GENERATOR_ALLOWED: # result = 1 -# cf.c_cf_flags |= CO_GENERATOR_ALLOWED +# flags |= CO_GENERATOR_ALLOWED +cf.c_cf_flags = rffi.cast(rffi.INT, flags) return result ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy speedup-list-comprehension: bump the pycode number and the sad case of renaming opcodes
Author: Maciej Fijalkowski fij...@gmail.com Branch: speedup-list-comprehension Changeset: r52824:287a83309e74 Date: 2012-02-23 18:35 -0700 http://bitbucket.org/pypy/pypy/changeset/287a83309e74/ Log:bump the pycode number and the sad case of renaming opcodes diff --git a/lib-python/modified-2.7/opcode.py b/lib-python/modified-2.7/opcode.py --- a/lib-python/modified-2.7/opcode.py +++ b/lib-python/modified-2.7/opcode.py @@ -119,39 +119,40 @@ def_op('POP_BLOCK', 87) def_op('END_FINALLY', 88) def_op('BUILD_CLASS', 89) +def_op('BUILD_LIST_FROM_ARG', 90) -HAVE_ARGUMENT = 90 # Opcodes from here have an argument: +HAVE_ARGUMENT = 91 # Opcodes from here have an argument: -name_op('STORE_NAME', 90) # Index in name list -name_op('DELETE_NAME', 91) # -def_op('UNPACK_SEQUENCE', 92) # Number of tuple items -jrel_op('FOR_ITER', 93) -def_op('LIST_APPEND', 94) -name_op('STORE_ATTR', 95) # Index in name list -name_op('DELETE_ATTR', 96) # -name_op('STORE_GLOBAL', 97) # -name_op('DELETE_GLOBAL', 98)# -def_op('DUP_TOPX', 99) # number of items to duplicate -def_op('LOAD_CONST', 100) # Index in const list -hasconst.append(100) -name_op('LOAD_NAME', 101) # Index in name list -def_op('BUILD_TUPLE', 102) # Number of tuple items -def_op('BUILD_LIST', 103) # Number of list items -def_op('BUILD_SET', 104)# Number of set items -def_op('BUILD_MAP', 105)# Number of dict entries (upto 255) -name_op('LOAD_ATTR', 106) # Index in name list -def_op('COMPARE_OP', 107) # Comparison operator -hascompare.append(107) -name_op('IMPORT_NAME', 108) # Index in name list -name_op('IMPORT_FROM', 109) # Index in name list -jrel_op('JUMP_FORWARD', 110)# Number of bytes to skip -jabs_op('JUMP_IF_FALSE_OR_POP', 111) # Target byte offset from beginning of code -jabs_op('JUMP_IF_TRUE_OR_POP', 112) # -jabs_op('JUMP_ABSOLUTE', 113)# -jabs_op('POP_JUMP_IF_FALSE', 114)# -jabs_op('POP_JUMP_IF_TRUE', 115) # +name_op('STORE_NAME', 91) # Index in name list +name_op('DELETE_NAME', 92) # +def_op('UNPACK_SEQUENCE', 93) # Number of tuple items +jrel_op('FOR_ITER', 94) +def_op('LIST_APPEND', 95) +name_op('STORE_ATTR', 96) # Index in name list +name_op('DELETE_ATTR', 97) # +name_op('STORE_GLOBAL', 98) # +name_op('DELETE_GLOBAL', 99)# +def_op('DUP_TOPX', 100) # number of items to duplicate +def_op('LOAD_CONST', 101) # Index in const list +hasconst.append(101) +name_op('LOAD_NAME', 102) # Index in name list +def_op('BUILD_TUPLE', 103) # Number of tuple items +def_op('BUILD_LIST', 104) # Number of list items +def_op('BUILD_SET', 105)# Number of set items +def_op('BUILD_MAP', 106)# Number of dict entries (upto 255) +name_op('LOAD_ATTR', 107) # Index in name list +def_op('COMPARE_OP', 108) # Comparison operator +hascompare.append(108) +name_op('IMPORT_NAME', 109) # Index in name list +name_op('IMPORT_FROM', 110) # Index in name list +jrel_op('JUMP_FORWARD', 111)# Number of bytes to skip +jabs_op('JUMP_IF_FALSE_OR_POP', 112) # Target byte offset from beginning of code +jabs_op('JUMP_IF_TRUE_OR_POP', 113) # +jabs_op('JUMP_ABSOLUTE', 114)# +jabs_op('POP_JUMP_IF_FALSE', 115)# +jabs_op('POP_JUMP_IF_TRUE', 116) # -name_op('LOAD_GLOBAL', 116) # Index in name list +name_op('LOAD_GLOBAL', 117) # Index in name list jabs_op('CONTINUE_LOOP', 119) # Target address jrel_op('SETUP_LOOP', 120) # Distance to target address @@ -192,6 +193,5 @@ def_op('LOOKUP_METHOD', 201) # Index in name list hasname.append(201) def_op('CALL_METHOD', 202)# #args not including 'self' -def_op('BUILD_LIST_FROM_ARG', 203) del def_op, name_op, jrel_op, jabs_op diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -28,7 +28,7 @@ # Magic numbers for the bytecode version in code objects. # See comments in pypy/module/imp/importing. cpython_magic, = struct.unpack(i, imp.get_magic()) # host magic number -default_magic = (168686339+2) | 0x0a0d # this PyPy's magic +default_magic = (168686339+3) | 0x0a0d # this PyPy's magic # (from CPython 2.7.0) # cpython_code_signature helper ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy speedup-list-comprehension: disable the code dump. A bit of progress when and how we emit the correct
Author: Maciej Fijalkowski fij...@gmail.com Branch: speedup-list-comprehension Changeset: r52825:b3406c3e63a4 Date: 2012-02-23 19:20 -0700 http://bitbucket.org/pypy/pypy/changeset/b3406c3e63a4/ Log:disable the code dump. A bit of progress when and how we emit the correct opcode. 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 @@ -965,7 +965,7 @@ self.emit_op_arg(ops.CALL_METHOD, (kwarg_count 8) | arg_count) return True -def _listcomp_generator(self, gens, gen_index, elt, outermost=False): +def _listcomp_generator(self, gens, gen_index, elt, emit_build=False): start = self.new_block() skip = self.new_block() if_cleanup = self.new_block() @@ -973,7 +973,7 @@ gen = gens[gen_index] assert isinstance(gen, ast.comprehension) gen.iter.walkabout(self) -if outermost: +if emit_build: self.emit_op(ops.BUILD_LIST_FROM_ARG) self.emit_op(ops.GET_ITER) self.use_next_block(start) @@ -1000,7 +1000,12 @@ def visit_ListComp(self, lc): self.update_position(lc.lineno) -self._listcomp_generator(lc.generators, 0, lc.elt, outermost=True) +if not lc.generators[0].ifs and len(lc.generators) == 1: +emit_build = True +else: +emit_build = False +self.emit_op_arg(ops.BUILD_LIST, 0) +self._listcomp_generator(lc.generators, 0, lc.elt, emit_build) def _comp_generator(self, node, generators, gen_index): start = self.new_block() diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -4,7 +4,7 @@ The bytecode interpreter itself is implemented by the PyFrame class. -import dis, imp, struct, types, new, sys +import imp, struct, types, new, sys, dis from pypy.interpreter import eval from pypy.interpreter.argument import Signature @@ -14,7 +14,6 @@ CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED, CO_GENERATOR, CO_CONTAINSGLOBALS) from pypy.rlib.rarithmetic import intmask -from pypy.rlib.debug import make_sure_not_resized from pypy.rlib import jit from pypy.rlib.objectmodel import compute_hash from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT @@ -265,6 +264,7 @@ def dump(self): A dis.dis() dump of the code object. +return co = self._to_code() dis.dis(co) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy speedup-list-comprehension: backout. not worth having a bytecode without arg
Author: Maciej Fijalkowski fij...@gmail.com Branch: speedup-list-comprehension Changeset: r52827:febd5ba50dab Date: 2012-02-23 19:31 -0700 http://bitbucket.org/pypy/pypy/changeset/febd5ba50dab/ Log:backout. not worth having a bytecode without arg diff --git a/lib-python/modified-2.7/opcode.py b/lib-python/modified-2.7/opcode.py --- a/lib-python/modified-2.7/opcode.py +++ b/lib-python/modified-2.7/opcode.py @@ -119,40 +119,39 @@ def_op('POP_BLOCK', 87) def_op('END_FINALLY', 88) def_op('BUILD_CLASS', 89) -def_op('BUILD_LIST_FROM_ARG', 90) -HAVE_ARGUMENT = 91 # Opcodes from here have an argument: +HAVE_ARGUMENT = 90 # Opcodes from here have an argument: -name_op('STORE_NAME', 91) # Index in name list -name_op('DELETE_NAME', 92) # -def_op('UNPACK_SEQUENCE', 93) # Number of tuple items -jrel_op('FOR_ITER', 94) -def_op('LIST_APPEND', 95) -name_op('STORE_ATTR', 96) # Index in name list -name_op('DELETE_ATTR', 97) # -name_op('STORE_GLOBAL', 98) # -name_op('DELETE_GLOBAL', 99)# -def_op('DUP_TOPX', 100) # number of items to duplicate -def_op('LOAD_CONST', 101) # Index in const list -hasconst.append(101) -name_op('LOAD_NAME', 102) # Index in name list -def_op('BUILD_TUPLE', 103) # Number of tuple items -def_op('BUILD_LIST', 104) # Number of list items -def_op('BUILD_SET', 105)# Number of set items -def_op('BUILD_MAP', 106)# Number of dict entries (upto 255) -name_op('LOAD_ATTR', 107) # Index in name list -def_op('COMPARE_OP', 108) # Comparison operator -hascompare.append(108) -name_op('IMPORT_NAME', 109) # Index in name list -name_op('IMPORT_FROM', 110) # Index in name list -jrel_op('JUMP_FORWARD', 111)# Number of bytes to skip -jabs_op('JUMP_IF_FALSE_OR_POP', 112) # Target byte offset from beginning of code -jabs_op('JUMP_IF_TRUE_OR_POP', 113) # -jabs_op('JUMP_ABSOLUTE', 114)# -jabs_op('POP_JUMP_IF_FALSE', 115)# -jabs_op('POP_JUMP_IF_TRUE', 116) # +name_op('STORE_NAME', 90) # Index in name list +name_op('DELETE_NAME', 91) # +def_op('UNPACK_SEQUENCE', 92) # Number of tuple items +jrel_op('FOR_ITER', 93) +def_op('LIST_APPEND', 94) +name_op('STORE_ATTR', 95) # Index in name list +name_op('DELETE_ATTR', 96) # +name_op('STORE_GLOBAL', 97) # +name_op('DELETE_GLOBAL', 98)# +def_op('DUP_TOPX', 99) # number of items to duplicate +def_op('LOAD_CONST', 100) # Index in const list +hasconst.append(100) +name_op('LOAD_NAME', 101) # Index in name list +def_op('BUILD_TUPLE', 102) # Number of tuple items +def_op('BUILD_LIST', 103) # Number of list items +def_op('BUILD_SET', 104)# Number of set items +def_op('BUILD_MAP', 105)# Number of dict entries (upto 255) +name_op('LOAD_ATTR', 106) # Index in name list +def_op('COMPARE_OP', 107) # Comparison operator +hascompare.append(107) +name_op('IMPORT_NAME', 108) # Index in name list +name_op('IMPORT_FROM', 109) # Index in name list +jrel_op('JUMP_FORWARD', 110)# Number of bytes to skip +jabs_op('JUMP_IF_FALSE_OR_POP', 111) # Target byte offset from beginning of code +jabs_op('JUMP_IF_TRUE_OR_POP', 112) # +jabs_op('JUMP_ABSOLUTE', 113)# +jabs_op('POP_JUMP_IF_FALSE', 114)# +jabs_op('POP_JUMP_IF_TRUE', 115) # -name_op('LOAD_GLOBAL', 117) # Index in name list +name_op('LOAD_GLOBAL', 116) # Index in name list jabs_op('CONTINUE_LOOP', 119) # Target address jrel_op('SETUP_LOOP', 120) # Distance to target address @@ -193,5 +192,6 @@ def_op('LOOKUP_METHOD', 201) # Index in name list hasname.append(201) def_op('CALL_METHOD', 202)# #args not including 'self' +def_op('BUILD_LIST_FROM_ARG', 203) del def_op, name_op, jrel_op, jabs_op diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -28,7 +28,7 @@ # Magic numbers for the bytecode version in code objects. # See comments in pypy/module/imp/importing. cpython_magic, = struct.unpack(i, imp.get_magic()) # host magic number -default_magic = (168686339+3) | 0x0a0d # this PyPy's magic +default_magic = (168686339+2) | 0x0a0d # this PyPy's magic # (from CPython 2.7.0) # cpython_code_signature helper ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy speedup-list-comprehension: Backed out changeset b3406c3e63a4
Author: Maciej Fijalkowski fij...@gmail.com Branch: speedup-list-comprehension Changeset: r52826:baf60af5868e Date: 2012-02-23 19:30 -0700 http://bitbucket.org/pypy/pypy/changeset/baf60af5868e/ Log:Backed out changeset b3406c3e63a4 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 @@ -965,7 +965,7 @@ self.emit_op_arg(ops.CALL_METHOD, (kwarg_count 8) | arg_count) return True -def _listcomp_generator(self, gens, gen_index, elt, emit_build=False): +def _listcomp_generator(self, gens, gen_index, elt, outermost=False): start = self.new_block() skip = self.new_block() if_cleanup = self.new_block() @@ -973,7 +973,7 @@ gen = gens[gen_index] assert isinstance(gen, ast.comprehension) gen.iter.walkabout(self) -if emit_build: +if outermost: self.emit_op(ops.BUILD_LIST_FROM_ARG) self.emit_op(ops.GET_ITER) self.use_next_block(start) @@ -1000,12 +1000,7 @@ def visit_ListComp(self, lc): self.update_position(lc.lineno) -if not lc.generators[0].ifs and len(lc.generators) == 1: -emit_build = True -else: -emit_build = False -self.emit_op_arg(ops.BUILD_LIST, 0) -self._listcomp_generator(lc.generators, 0, lc.elt, emit_build) +self._listcomp_generator(lc.generators, 0, lc.elt, outermost=True) def _comp_generator(self, node, generators, gen_index): start = self.new_block() diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -4,7 +4,7 @@ The bytecode interpreter itself is implemented by the PyFrame class. -import imp, struct, types, new, sys, dis +import dis, imp, struct, types, new, sys from pypy.interpreter import eval from pypy.interpreter.argument import Signature @@ -14,6 +14,7 @@ CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED, CO_GENERATOR, CO_CONTAINSGLOBALS) from pypy.rlib.rarithmetic import intmask +from pypy.rlib.debug import make_sure_not_resized from pypy.rlib import jit from pypy.rlib.objectmodel import compute_hash from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT @@ -264,7 +265,6 @@ def dump(self): A dis.dis() dump of the code object. -return co = self._to_code() dis.dis(co) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy speedup-list-comprehension: redo the reasonable part
Author: Maciej Fijalkowski fij...@gmail.com Branch: speedup-list-comprehension Changeset: r52828:45a68e50a262 Date: 2012-02-23 19:34 -0700 http://bitbucket.org/pypy/pypy/changeset/45a68e50a262/ Log:redo the reasonable part 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 @@ -965,7 +965,7 @@ self.emit_op_arg(ops.CALL_METHOD, (kwarg_count 8) | arg_count) return True -def _listcomp_generator(self, gens, gen_index, elt, outermost=False): +def _listcomp_generator(self, gens, gen_index, elt, single=False): start = self.new_block() skip = self.new_block() if_cleanup = self.new_block() @@ -973,8 +973,8 @@ gen = gens[gen_index] assert isinstance(gen, ast.comprehension) gen.iter.walkabout(self) -if outermost: -self.emit_op(ops.BUILD_LIST_FROM_ARG) +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) @@ -1000,7 +1000,12 @@ def visit_ListComp(self, lc): self.update_position(lc.lineno) -self._listcomp_generator(lc.generators, 0, lc.elt, outermost=True) +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() ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy speedup-list-comprehension: remove confusing oopspecs
Author: Maciej Fijalkowski fij...@gmail.com Branch: speedup-list-comprehension Changeset: r52829:19b8e4c5fe4f Date: 2012-02-23 20:05 -0700 http://bitbucket.org/pypy/pypy/changeset/19b8e4c5fe4f/ Log:remove confusing oopspecs 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 @@ -262,7 +262,6 @@ l.items = malloc(LIST.items.TO, length) return l ll_newlist = typeMethod(ll_newlist) -ll_newlist.oopspec = 'newlist(length)' def ll_newlist_hint(LIST, lengthhint): ll_assert(lengthhint = 0, negative list length) @@ -271,7 +270,6 @@ l.items = malloc(LIST.items.TO, lengthhint) return l ll_newlist_hint = typeMethod(ll_newlist_hint) -ll_newlist_hint.oopspec = 'newlist(lengthhint)' # should empty lists start with no allocated memory, or with a preallocated # minimal number of entries? XXX compare memory usage versus speed, and @@ -294,11 +292,9 @@ l.items = _ll_new_empty_item_array(LIST) return l ll_newemptylist = typeMethod(ll_newemptylist) -ll_newemptylist.oopspec = 'newlist(0)' def ll_length(l): return l.length -ll_length.oopspec = 'list.len(l)' def ll_items(l): return l.items @@ -306,12 +302,10 @@ def ll_getitem_fast(l, index): ll_assert(index l.length, getitem out of bounds) return l.ll_items()[index] -ll_getitem_fast.oopspec = 'list.getitem(l, index)' def ll_setitem_fast(l, index, item): ll_assert(index l.length, setitem out of bounds) l.ll_items()[index] = item -ll_setitem_fast.oopspec = 'list.setitem(l, index, item)' # fixed size versions @@ -320,15 +314,12 @@ l = malloc(LIST, length) return l ll_fixed_newlist = typeMethod(ll_fixed_newlist) -ll_fixed_newlist.oopspec = 'newlist(length)' def ll_fixed_newemptylist(LIST): return ll_fixed_newlist(LIST, 0) -ll_fixed_newemptylist = typeMethod(ll_fixed_newemptylist) def ll_fixed_length(l): return len(l) -ll_fixed_length.oopspec = 'list.len(l)' def ll_fixed_items(l): return l @@ -336,12 +327,10 @@ def ll_fixed_getitem_fast(l, index): ll_assert(index len(l), fixed getitem out of bounds) return l[index] -ll_fixed_getitem_fast.oopspec = 'list.getitem(l, index)' def ll_fixed_setitem_fast(l, index, item): ll_assert(index len(l), fixed setitem out of bounds) l[index] = item -ll_fixed_setitem_fast.oopspec = 'list.setitem(l, index, item)' def newlist(llops, r_list, items_v, v_sizehint=None): LIST = r_list.LIST ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy speedup-list-comprehension: merge default
Author: Maciej Fijalkowski fij...@gmail.com Branch: speedup-list-comprehension Changeset: r52830:5b39d23e1c0e Date: 2012-02-23 20:10 -0700 http://bitbucket.org/pypy/pypy/changeset/5b39d23e1c0e/ Log:merge default diff --git a/pypy/module/_io/__init__.py b/pypy/module/_io/__init__.py --- a/pypy/module/_io/__init__.py +++ b/pypy/module/_io/__init__.py @@ -28,6 +28,7 @@ } def init(self, space): +MixedModule.init(self, space) w_UnsupportedOperation = space.call_function( space.w_type, space.wrap('UnsupportedOperation'), @@ -35,3 +36,9 @@ space.newdict()) space.setattr(self, space.wrap('UnsupportedOperation'), w_UnsupportedOperation) + +def shutdown(self, space): +# at shutdown, flush all open streams. Ignore I/O errors. +from pypy.module._io.interp_iobase import get_autoflushher +get_autoflushher(space).flush_all(space) + diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -5,6 +5,8 @@ from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rlib.rstring import StringBuilder +from pypy.rlib import rweakref + DEFAULT_BUFFER_SIZE = 8192 @@ -43,6 +45,8 @@ self.space = space self.w_dict = space.newdict() self.__IOBase_closed = False +self.streamholder = None # needed by AutoFlusher +get_autoflushher(space).add(self) def getdict(self, space): return self.w_dict @@ -98,6 +102,7 @@ space.call_method(self, flush) finally: self.__IOBase_closed = True +get_autoflushher(space).remove(self) def flush_w(self, space): if self._CLOSED(): @@ -303,3 +308,52 @@ read = interp2app(W_RawIOBase.read_w), readall = interp2app(W_RawIOBase.readall_w), ) + + +# +# functions to make sure that all streams are flushed on exit +# + +class StreamHolder(object): + +def __init__(self, w_iobase): +self.w_iobase_ref = rweakref.ref(w_iobase) +w_iobase.autoflusher = self + +def autoflush(self, space): +w_iobase = self.w_iobase_ref() +if w_iobase is not None: +space.call_method(w_iobase, 'flush') # XXX: ignore IOErrors? + + +class AutoFlusher(object): + +def __init__(self, space): +self.streams = {} + +def add(self, w_iobase): +assert w_iobase.streamholder is None +holder = StreamHolder(w_iobase) +w_iobase.streamholder = holder +self.streams[holder] = None + +def remove(self, w_iobase): +holder = w_iobase.streamholder +if holder is not None: +del self.streams[holder] + +def flush_all(self, space): +while self.streams: +for streamholder in self.streams.keys(): +try: +del self.streams[streamholder] +except KeyError: +pass# key was removed in the meantime +else: +streamholder.autoflush(space) + + +def get_autoflushher(space): +return space.fromcache(AutoFlusher) + + 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 @@ -160,3 +160,20 @@ f.close() assert repr(f) == _io.FileIO [closed] +def test_flush_at_exit(): +from pypy import conftest +from pypy.tool.option import make_config, make_objspace +from pypy.tool.udir import udir + +tmpfile = udir.join('test_flush_at_exit') +config = make_config(conftest.option) +space = make_objspace(config) +space.appexec([space.wrap(str(tmpfile))], (tmpfile): +import io +f = io.open(tmpfile, 'w') +f.write('42') +# no flush() and no close() +import sys; sys._keepalivesomewhereobscure = f +) +space.finish() +assert tmpfile.read() == '42' diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -469,15 +469,16 @@ # FLOATs. if len(self._heuristic_order) len(livevars): from pypy.rlib.rarithmetic import (r_singlefloat, r_longlong, - r_ulonglong) + r_ulonglong, r_uint) added = False for var, value in livevars.items(): if var not in self._heuristic_order: -if isinstance(value, (r_longlong, r_ulonglong)): -pass -#assert 0, (should not pass a r_longlong argument for -#
[pypy-commit] pypy speedup-list-comprehension: removing this was accidental
Author: Maciej Fijalkowski fij...@gmail.com Branch: speedup-list-comprehension Changeset: r52831:67935212c8c2 Date: 2012-02-23 20:21 -0700 http://bitbucket.org/pypy/pypy/changeset/67935212c8c2/ Log:removing this was accidental 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 @@ -309,12 +309,13 @@ # fixed size versions +@typeMethod def ll_fixed_newlist(LIST, length): ll_assert(length = 0, negative fixed list length) l = malloc(LIST, length) return l -ll_fixed_newlist = typeMethod(ll_fixed_newlist) +@typeMethod def ll_fixed_newemptylist(LIST): return ll_fixed_newlist(LIST, 0) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit