From fijal at codespeak.net Wed Oct 1 10:30:54 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 10:30:54 +0200 (CEST) Subject: [pypy-svn] r58515 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081001083054.F23D216A082@codespeak.net> Author: fijal Date: Wed Oct 1 10:30:52 2008 New Revision: 58515 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Update comment to explain what this code do Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 1 10:30:52 2008 @@ -23,17 +23,23 @@ # so, the idea as now is: -# we allocate space (full of zeroes) which is big enough to handle -# all possible cases. Because it's full of zeroes, we never allocate -# it really, unless we start using it - -# for each collection we mark objects which are alive, also marking all -# for which we want to run finalizers. we mark them by storing forward -# pointer, which will be a place to copy them. After that, we copy all -# using memmove to another view of the same space, hence compacting -# everything - -# before compacting, we update forward references to pointers +# this gc works more or less like semispace, but has some essential +# differencies. The main difference is that we have separate phases of +# marking and assigning pointers, hence order of objects is preserved. +# This means we can reuse the same space if it did not grow enough. +# More importantly, in case we need to resize space we can copy it bit by +# bit, hence avoiding double memory consumption at peak times + +# so the algorithm itself is performed in 3 stages (module weakrefs and +# finalizers) + +# 1. We mark alive objects +# 2. We walk all objects and assign forward pointers in the same order, +# also updating all references +# 3. We compact the space by moving. In case we move to the same space, +# we use arena_new_view trick, which looks like new space to tests, +# but compiles to the same pointer. Also we use raw_memmove in case +# objects overlap. class MarkCompactGC(MovingGCBase): HDR = lltype.Struct('header', ('tid', lltype.Signed), From arigo at codespeak.net Wed Oct 1 12:59:19 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 1 Oct 2008 12:59:19 +0200 (CEST) Subject: [pypy-svn] r58520 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081001105919.05EEA16A06A@codespeak.net> Author: arigo Date: Wed Oct 1 12:59:18 2008 New Revision: 58520 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: No point in replacing the empty deque with a new empty deque. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 1 12:59:18 2008 @@ -353,8 +353,6 @@ obj = self.finalizers_to_run.popleft() finalizer = self.getfinalizer(self.get_type_id(obj)) finalizer(obj) - self.finalizers_to_run.delete() - self.finalizers_to_run = self.AddressDeque() def invalidate_weakrefs(self): # walk over list of objects that contain weakrefs From fijal at codespeak.net Wed Oct 1 13:10:09 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 13:10:09 +0200 (CEST) Subject: [pypy-svn] r58521 - in pypy/branch/gc-experiments/pypy/rpython/memory: gc test Message-ID: <20081001111009.B8E3A169FA4@codespeak.net> Author: fijal Date: Wed Oct 1 13:10:08 2008 New Revision: 58521 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Log: Improve a bit. Use better algorithm for looking at objects, add more tests, implement space resizing Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py Wed Oct 1 13:10:08 2008 @@ -208,6 +208,7 @@ self.finalizer_lock_count = 0 self.id_free_list = self.AddressStack() self.next_free_id = 1 + self.red_zone = 0 def setup(self): self.objects_with_finalizers = self.AddressDeque() @@ -252,6 +253,22 @@ size = llarena.round_up_for_allocation(size) return size + def record_red_zone(self): + # red zone: if the space is more than 80% full, the next collection + # should double its size. If it is more than 66% full twice in a row, + # then it should double its size too. (XXX adjust) + # The goal is to avoid many repeated collection that don't free a lot + # of memory each, if the size of the live object set is just below the + # size of the space. + free_after_collection = self.top_of_space - self.free + if free_after_collection > self.space_size // 3: + self.red_zone = 0 + else: + self.red_zone += 1 + if free_after_collection < self.space_size // 5: + self.red_zone += 1 + + def choose_gc_from_config(config): """Return a (GCClass, GC_PARAMS) from the given config object. """ Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 1 13:10:08 2008 @@ -41,29 +41,26 @@ # but compiles to the same pointer. Also we use raw_memmove in case # objects overlap. +# in case we need to grow space, we use +# current_space_size * FREE_SPACE_MULTIPLIER / FREE_SPACE_DIVIDER + needed +FREE_SPACE_MULTIPLIER = 3 +FREE_SPACE_DIVIDER = 2 + class MarkCompactGC(MovingGCBase): HDR = lltype.Struct('header', ('tid', lltype.Signed), ('forward_ptr', llmemory.Address)) - # XXX probably we need infinite (ie 4G) amount of memory here - # and we'll keep all pages shared. The question is what we do - # with tests which create all llarenas - - TRANSLATION_PARAMS = {'space_size': 16*1024*1024} # XXX adjust - - def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=16*(1024**2)): - # space_size should be maximal available virtual memory. - # this way we'll never need to copy anything nor implement - # paging on our own + TRANSLATION_PARAMS = {'space_size': 2*1024*1024} # XXX adjust + + def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=2*(1024**2)): self.space_size = space_size MovingGCBase.__init__(self, chunk_size) - self.counter = 0 def setup(self): self.space = llarena.arena_malloc(self.space_size, True) ll_assert(bool(self.space), "couldn't allocate arena") - self.spaceptr = self.space - self.toaddr = self.space + self.free = self.space + self.top_of_space = self.space + self.space_size MovingGCBase.setup(self) self.finalizers_to_run = self.AddressDeque() @@ -77,11 +74,14 @@ assert can_collect size_gc_header = self.gcheaderbuilder.size_gc_header totalsize = size_gc_header + size - self.eventually_collect() - result = self.spaceptr + result = self.free + if raw_malloc_usage(totalsize) > self.top_of_space - result: + if not can_collect: + raise memoryError + result = self.obtain_free_space(totalsize) llarena.arena_reserve(result, totalsize) self.init_gc_object(result, typeid) - self.spaceptr += totalsize + self.free += totalsize if has_finalizer: self.objects_with_finalizers.append(result + size_gc_header) if contains_weakptr: @@ -99,44 +99,96 @@ totalsize = ovfcheck(nonvarsize + varsize) except OverflowError: raise memoryError - self.eventually_collect() - result = self.spaceptr + result = self.free + if raw_malloc_usage(totalsize) > self.top_of_space - result: + if not can_collect: + raise memoryError + result = self.obtain_free_space(totalsize) llarena.arena_reserve(result, totalsize) self.init_gc_object(result, typeid) (result + size_gc_header + offset_to_length).signed[0] = length - self.spaceptr = result + llarena.round_up_for_allocation(totalsize) + self.free = result + llarena.round_up_for_allocation(totalsize) if has_finalizer: self.objects_with_finalizers.append(result + size_gc_header) return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF) - def eventually_collect(self): - # XXX this is a very bad idea, come up with better heuristics - # XXX it also does not check can_collect flag - self.counter += 1 - if self.counter == 1000: - self.collect() - self.counter = 0 + def obtain_free_space(self, totalsize): + # a bit of tweaking to maximize the performance and minimize the + # amount of code in an inlined version of malloc_fixedsize_clear() + if not self.try_obtain_free_space(totalsize): + raise memoryError + return self.free + obtain_free_space._dont_inline_ = True + + def try_obtain_free_space(self, needed): + needed = raw_malloc_usage(needed) + missing = needed - (self.top_of_space - self.free) + if (self.red_zone >= 2 and self.increase_space_size(needed)): + return True + else: + self.markcompactcollect() + missing = needed - (self.top_of_space - self.free) + if missing <= 0: + return True # success + else: + # first check if the object could possibly fit + if not self.increase_space_size(needed): + return False + return True + + def new_space_size(self, incr): + return (self.space_size * FREE_SPACE_MULTIPLIER / + FREE_SPACE_DIVIDER + incr) + + def increase_space_size(self, needed): + self.red_zone = 0 + new_size = self.new_space_size(needed) + newspace = llarena.arena_malloc(new_size, True) + if not newspace: + return False + self.tospace = newspace + self.space_size = new_size + self.markcompactcollect(resizing=True) + return True def collect(self): + self.markcompactcollect() + + def markcompactcollect(self, resizing=False): self.debug_check_consistency() - toaddr = llarena.arena_new_view(self.space) + if resizing: + toaddr = self.tospace + else: + toaddr = llarena.arena_new_view(self.space) + self.to_see = self.AddressStack() + if self.objects_with_finalizers.non_empty(): + self.mark_objects_with_finalizers() self.mark_roots_recursively() self.debug_check_consistency() #if self.run_finalizers.non_empty(): # self.update_run_finalizers() - if self.objects_with_finalizers.non_empty(): - self.mark_objects_with_finalizers() - if self.finalizers_to_run.non_empty(): - self.execute_finalizers() self.debug_check_consistency() finaladdr = self.update_forward_pointers(toaddr) if self.objects_with_weakrefs.non_empty(): self.invalidate_weakrefs() self.update_objects_with_id() - self.compact() - self.space = toaddr - self.spaceptr = finaladdr + self.update_finalizers_to_run() + self.compact(resizing) + self.space = toaddr + self.free = finaladdr + self.top_of_space = toaddr + self.space_size self.debug_check_consistency() + if not resizing: + self.record_red_zone() + if self.finalizers_to_run.non_empty(): + self.execute_finalizers() + + def update_finalizers_to_run(self): + finalizers_to_run = self.AddressDeque() + while self.finalizers_to_run.non_empty(): + obj = self.finalizers_to_run.popleft() + finalizers_to_run.append(self.get_forwarding_address(obj)) + self.finalizers_to_run = finalizers_to_run def get_type_id(self, addr): return self.header(addr).tid & TYPEID_MASK @@ -146,9 +198,21 @@ MarkCompactGC._mark_root_recursively, # stack roots MarkCompactGC._mark_root_recursively, # static in prebuilt non-gc structures MarkCompactGC._mark_root_recursively) # static in prebuilt gc objects + while self.to_see.non_empty(): + obj = self.to_see.pop() + self.trace(obj, self._mark_obj, None) + self.to_see.delete() + + def _mark_obj(self, pointer, ignored): + obj = pointer.address[0] + if obj != NULL: + if self.marked(obj): + return + self.mark(obj) + self.to_see.append(obj) def _mark_root_recursively(self, root): - self.trace_and_mark(root.address[0]) + self.to_see.append(root.address[0]) def mark(self, obj): self.header(obj).tid |= GCFLAG_MARKBIT @@ -156,29 +220,10 @@ def marked(self, obj): return self.header(obj).tid & GCFLAG_MARKBIT - def trace_and_mark(self, obj): - if self.marked(obj): - return - self.mark(obj) - to_see = self.AddressStack() - to_see.append(obj) - while to_see.non_empty(): - obj = to_see.pop() - self.trace(obj, self._mark_obj, to_see) - to_see.delete() - - def _mark_obj(self, pointer, to_see): - obj = pointer.address[0] - if obj != NULL: - if self.marked(obj): - return - self.mark(obj) - to_see.append(obj) - def update_forward_pointers(self, toaddr): fromaddr = self.space size_gc_header = self.gcheaderbuilder.size_gc_header - while fromaddr < self.spaceptr: + while fromaddr < self.free: hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) obj = fromaddr + size_gc_header objsize = self.get_size(obj) @@ -197,7 +242,7 @@ MarkCompactGC._update_root, # static in prebuilt non-gc structures MarkCompactGC._update_root) # static in prebuilt gc objects fromaddr = self.space - while fromaddr < self.spaceptr: + while fromaddr < self.free: hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) obj = fromaddr + size_gc_header objsize = self.get_size(obj) @@ -236,10 +281,10 @@ def surviving(self, obj): return self.header(obj).forward_ptr != NULL - def compact(self): + def compact(self, resizing): fromaddr = self.space size_gc_header = self.gcheaderbuilder.size_gc_header - while fromaddr < self.spaceptr: + while fromaddr < self.free: hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) obj = fromaddr + size_gc_header objsize = self.get_size(obj) @@ -264,7 +309,6 @@ # not sure what to check here pass - def id(self, ptr): obj = llmemory.cast_ptr_to_adr(ptr) if self.header(obj).tid & GCFLAG_EXTERNAL: @@ -344,7 +388,8 @@ new_with_finalizers.append(x) else: finalizers_to_run.append(x) - self.trace_and_mark(x) + self.mark(x) + self.to_see.append(x) self.objects_with_finalizers.delete() self.objects_with_finalizers = new_with_finalizers Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py Wed Oct 1 13:10:08 2008 @@ -41,7 +41,6 @@ MovingGCBase.__init__(self, chunk_size) self.space_size = space_size self.max_space_size = max_space_size - self.red_zone = 0 def setup(self): if DEBUG_PRINT: Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Wed Oct 1 13:10:08 2008 @@ -469,7 +469,9 @@ def test_weakref_to_object_with_finalizer(self): py.test.skip("Not implemented yet") - + +class TestMarkCompactGCGrowing(TestMarkCompactGC): + GC_PARAMS = {'space_size': 64} class TestHybridGC(TestGenerationalGC): from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass From fijal at codespeak.net Wed Oct 1 13:25:40 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 13:25:40 +0200 (CEST) Subject: [pypy-svn] r58522 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081001112540.A9D9E169F7F@codespeak.net> Author: fijal Date: Wed Oct 1 13:25:38 2008 New Revision: 58522 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Fixes to pass basic tests again Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 1 13:25:38 2008 @@ -209,9 +209,10 @@ if self.marked(obj): return self.mark(obj) - self.to_see.append(obj) + self.to_see.append(obj) def _mark_root_recursively(self, root): + self.mark(root.address[0]) self.to_see.append(root.address[0]) def mark(self, obj): @@ -307,7 +308,9 @@ def debug_check_object(self, obj): # not sure what to check here - pass + return + if self._is_external(obj): + assert not self.marked(self.header(obj)) and not self.surviving(obj) def id(self, ptr): obj = llmemory.cast_ptr_to_adr(ptr) From fijal at codespeak.net Wed Oct 1 13:36:22 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 13:36:22 +0200 (CEST) Subject: [pypy-svn] r58523 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081001113622.BEBFE16A071@codespeak.net> Author: fijal Date: Wed Oct 1 13:36:22 2008 New Revision: 58523 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Wuaaaaa! Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 1 13:36:22 2008 @@ -164,10 +164,8 @@ if self.objects_with_finalizers.non_empty(): self.mark_objects_with_finalizers() self.mark_roots_recursively() - self.debug_check_consistency() #if self.run_finalizers.non_empty(): # self.update_run_finalizers() - self.debug_check_consistency() finaladdr = self.update_forward_pointers(toaddr) if self.objects_with_weakrefs.non_empty(): self.invalidate_weakrefs() @@ -297,21 +295,19 @@ ll_assert(self.is_forwarded(obj), "not forwarded, surviving obj") forward_ptr = hdr.forward_ptr hdr.forward_ptr = NULL - hdr.tid &= ~(GCFLAG_MARKBIT&GCFLAG_FINALIZATION_ORDERING) + hdr.tid &= ~(GCFLAG_MARKBIT|GCFLAG_FINALIZATION_ORDERING) #llop.debug_print(lltype.Void, fromaddr, "copied to", forward_ptr, # "\ntid", self.header(obj).tid, # "\nsize", totalsize) llmemory.raw_memmove(fromaddr, forward_ptr, totalsize) llarena.arena_reset(fromaddr, totalsize, False) - assert llmemory.cast_adr_to_ptr(forward_ptr, lltype.Ptr(self.HDR)).tid fromaddr += totalsize def debug_check_object(self, obj): # not sure what to check here - return - if self._is_external(obj): - assert not self.marked(self.header(obj)) and not self.surviving(obj) - + ll_assert(not self.marked(obj), "Marked") + ll_assert(not self.surviving(obj), "forward_ptr set") + def id(self, ptr): obj = llmemory.cast_ptr_to_adr(ptr) if self.header(obj).tid & GCFLAG_EXTERNAL: From fijal at codespeak.net Wed Oct 1 14:04:47 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 14:04:47 +0200 (CEST) Subject: [pypy-svn] r58524 - in pypy/branch/gc-experiments/pypy/rpython/memory: gc test Message-ID: <20081001120447.EABCD16A06E@codespeak.net> Author: fijal Date: Wed Oct 1 14:04:45 2008 New Revision: 58524 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py Log: bits of fixes. Also add some constant size when resizing arena Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 1 14:04:45 2008 @@ -45,6 +45,7 @@ # current_space_size * FREE_SPACE_MULTIPLIER / FREE_SPACE_DIVIDER + needed FREE_SPACE_MULTIPLIER = 3 FREE_SPACE_DIVIDER = 2 +FREE_SPACE_ADD = 256 class MarkCompactGC(MovingGCBase): HDR = lltype.Struct('header', ('tid', lltype.Signed), @@ -62,7 +63,7 @@ self.free = self.space self.top_of_space = self.space + self.space_size MovingGCBase.setup(self) - self.finalizers_to_run = self.AddressDeque() + self.run_finalizers = self.AddressDeque() def init_gc_object(self, addr, typeid, flags=0): hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) @@ -138,7 +139,7 @@ def new_space_size(self, incr): return (self.space_size * FREE_SPACE_MULTIPLIER / - FREE_SPACE_DIVIDER + incr) + FREE_SPACE_DIVIDER + incr + FREE_SPACE_ADD) def increase_space_size(self, needed): self.red_zone = 0 @@ -161,16 +162,16 @@ else: toaddr = llarena.arena_new_view(self.space) self.to_see = self.AddressStack() - if self.objects_with_finalizers.non_empty(): + if (self.objects_with_finalizers.non_empty() or + self.run_finalizers.non_empty()): self.mark_objects_with_finalizers() self.mark_roots_recursively() - #if self.run_finalizers.non_empty(): - # self.update_run_finalizers() finaladdr = self.update_forward_pointers(toaddr) + if self.run_finalizers.non_empty(): + self.update_run_finalizers() if self.objects_with_weakrefs.non_empty(): self.invalidate_weakrefs() self.update_objects_with_id() - self.update_finalizers_to_run() self.compact(resizing) self.space = toaddr self.free = finaladdr @@ -178,15 +179,15 @@ self.debug_check_consistency() if not resizing: self.record_red_zone() - if self.finalizers_to_run.non_empty(): + if self.run_finalizers.non_empty(): self.execute_finalizers() - def update_finalizers_to_run(self): - finalizers_to_run = self.AddressDeque() - while self.finalizers_to_run.non_empty(): - obj = self.finalizers_to_run.popleft() - finalizers_to_run.append(self.get_forwarding_address(obj)) - self.finalizers_to_run = finalizers_to_run + def update_run_finalizers(self): + run_finalizers = self.AddressDeque() + while self.run_finalizers.non_empty(): + obj = self.run_finalizers.popleft() + run_finalizers.append(self.get_forwarding_address(obj)) + self.run_finalizers = run_finalizers def get_type_id(self, addr): return self.header(addr).tid & TYPEID_MASK @@ -305,8 +306,9 @@ def debug_check_object(self, obj): # not sure what to check here - ll_assert(not self.marked(obj), "Marked") - ll_assert(not self.surviving(obj), "forward_ptr set") + if not self._is_external(obj): + ll_assert(not self.marked(obj), "Marked") + ll_assert(not self.surviving(obj), "forward_ptr set") def id(self, ptr): obj = llmemory.cast_ptr_to_adr(ptr) @@ -364,39 +366,40 @@ else: self.id_free_list.append(id) - def _finalization_state(self, obj): - if self.surviving(obj): - hdr = self.header(obj) - if hdr.tid & GCFLAG_FINALIZATION_ORDERING: - return 2 - else: - return 3 - else: - hdr = self.header(obj) - if hdr.tid & GCFLAG_FINALIZATION_ORDERING: - return 1 - else: - return 0 - def mark_objects_with_finalizers(self): new_with_finalizers = self.AddressDeque() - finalizers_to_run = self.finalizers_to_run + run_finalizers = self.run_finalizers + new_run_finalizers = self.AddressDeque() + while run_finalizers.non_empty(): + x = run_finalizers.popleft() + self.mark(x) + self.to_see.append(x) + new_run_finalizers.append(x) + run_finalizers.delete() + self.run_finalizers = new_run_finalizers while self.objects_with_finalizers.non_empty(): x = self.objects_with_finalizers.popleft() if self.marked(x): new_with_finalizers.append(x) else: - finalizers_to_run.append(x) + new_run_finalizers.append(x) self.mark(x) self.to_see.append(x) self.objects_with_finalizers.delete() self.objects_with_finalizers = new_with_finalizers def execute_finalizers(self): - while self.finalizers_to_run.non_empty(): - obj = self.finalizers_to_run.popleft() - finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj) + self.finalizer_lock_count += 1 + try: + while self.run_finalizers.non_empty(): + if self.finalizer_lock_count > 1: + # the outer invocation of execute_finalizers() will do it + break + obj = self.run_finalizers.popleft() + finalizer = self.getfinalizer(self.get_type_id(obj)) + finalizer(obj) + finally: + self.finalizer_lock_count -= 1 def invalidate_weakrefs(self): # walk over list of objects that contain weakrefs Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py Wed Oct 1 14:04:45 2008 @@ -364,6 +364,7 @@ persistent_a4 = A() llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) + llop.gc__collect(lltype.Void) b.bla = persistent_a1.id + persistent_a2.id + persistent_a3.id + persistent_a4.id return b.num_deleted run = self.runner(f, nbargs=2) From fijal at codespeak.net Wed Oct 1 14:05:37 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 14:05:37 +0200 (CEST) Subject: [pypy-svn] r58525 - pypy/branch/gc-experiments/pypy/rpython/memory/test Message-ID: <20081001120537.68B7D16A06E@codespeak.net> Author: fijal Date: Wed Oct 1 14:05:36 2008 New Revision: 58525 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py Log: didn't mean to check this in Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py Wed Oct 1 14:05:36 2008 @@ -364,7 +364,6 @@ persistent_a4 = A() llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) - llop.gc__collect(lltype.Void) b.bla = persistent_a1.id + persistent_a2.id + persistent_a3.id + persistent_a4.id return b.num_deleted run = self.runner(f, nbargs=2) From fijal at codespeak.net Wed Oct 1 14:09:17 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 14:09:17 +0200 (CEST) Subject: [pypy-svn] r58526 - pypy/branch/gc-experiments/pypy/rpython/memory/test Message-ID: <20081001120917.C0D0616A067@codespeak.net> Author: fijal Date: Wed Oct 1 14:09:17 2008 New Revision: 58526 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Log: These tests should pass now. (One doesn't, but that's a bug) Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Wed Oct 1 14:09:17 2008 @@ -461,15 +461,6 @@ def test_finalizer_order(self): py.test.skip("Not implemented yet") - def test_finalizer_calls_malloc(self): - py.test.skip("Not implemented yet") - - def test_finalizer_calls_malloc_during_minor_collect(self): - py.test.skip("Not implemented yet") - - def test_weakref_to_object_with_finalizer(self): - py.test.skip("Not implemented yet") - class TestMarkCompactGCGrowing(TestMarkCompactGC): GC_PARAMS = {'space_size': 64} From fijal at codespeak.net Wed Oct 1 14:29:47 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 14:29:47 +0200 (CEST) Subject: [pypy-svn] r58527 - in pypy/branch/gc-experiments/pypy/rpython/lltypesystem: . test Message-ID: <20081001122947.27D9A169E76@codespeak.net> Author: fijal Date: Wed Oct 1 14:29:45 2008 New Revision: 58527 Modified: pypy/branch/gc-experiments/pypy/rpython/lltypesystem/llmemory.py pypy/branch/gc-experiments/pypy/rpython/lltypesystem/test/test_llmemory.py Log: Add _free in raw_memmove (and a test) Modified: pypy/branch/gc-experiments/pypy/rpython/lltypesystem/llmemory.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/lltypesystem/llmemory.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/lltypesystem/llmemory.py Wed Oct 1 14:29:45 2008 @@ -738,8 +738,9 @@ def raw_memmove(source, dest, size): # for now let's assume that raw_memmove is the same as raw_memcopy, - # when run on top of fake addresses + # when run on top of fake addresses, but we _free the source object raw_memcopy(source, dest, size) + source.ptr._as_obj()._free() def cast_any_ptr(EXPECTED_TYPE, ptr): # this is a generalization of the various cast_xxx_ptr() functions. Modified: pypy/branch/gc-experiments/pypy/rpython/lltypesystem/test/test_llmemory.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/lltypesystem/test/test_llmemory.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/lltypesystem/test/test_llmemory.py Wed Oct 1 14:29:45 2008 @@ -504,6 +504,18 @@ raw_memcopy(at1, at2, sizeof(T)) assert t2.x == 1 +def test_raw_memmove(): + T = lltype.GcStruct('T', ('x', lltype.Signed)) + t1 = lltype.malloc(T) + t2 = lltype.malloc(T) + t1.x = 1 + t2.x = 2 + at1 = cast_ptr_to_adr(t1) + at2 = cast_ptr_to_adr(t2) + raw_memmove(at1, at2, sizeof(T)) + assert t2.x == 1 + py.test.raises(RuntimeError, "t1.x") + def test_raw_memcopy_nonrec(): T = lltype.GcStruct('T', ('x', lltype.Signed)) A = lltype.FixedSizeArray(lltype.Ptr(T), 1) From fijal at codespeak.net Wed Oct 1 19:29:26 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 19:29:26 +0200 (CEST) Subject: [pypy-svn] r58534 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081001172926.2398B169FD7@codespeak.net> Author: fijal Date: Wed Oct 1 19:29:24 2008 New Revision: 58534 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Remove arena_reset here Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 1 19:29:24 2008 @@ -53,6 +53,10 @@ TRANSLATION_PARAMS = {'space_size': 2*1024*1024} # XXX adjust + malloc_zero_filled = True + inline_simple_malloc = True + inline_simple_malloc_varsize = True + def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=2*(1024**2)): self.space_size = space_size MovingGCBase.__init__(self, chunk_size) @@ -301,7 +305,7 @@ # "\ntid", self.header(obj).tid, # "\nsize", totalsize) llmemory.raw_memmove(fromaddr, forward_ptr, totalsize) - llarena.arena_reset(fromaddr, totalsize, False) + #llarena.arena_reset(fromaddr, totalsize, False) fromaddr += totalsize def debug_check_object(self, obj): From fijal at codespeak.net Wed Oct 1 19:30:34 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 1 Oct 2008 19:30:34 +0200 (CEST) Subject: [pypy-svn] r58535 - in pypy/branch/gc-experiments/pypy/rpython/memory: gc test Message-ID: <20081001173034.EF056169E14@codespeak.net> Author: fijal Date: Wed Oct 1 19:30:34 2008 New Revision: 58535 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py Log: Don't clear the arena here Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 1 19:30:34 2008 @@ -294,8 +294,8 @@ objsize = self.get_size(obj) totalsize = size_gc_header + objsize if not self.surviving(obj): - # this object dies, clear arena - llarena.arena_reset(fromaddr, totalsize, True) + # this object dies + pass else: ll_assert(self.is_forwarded(obj), "not forwarded, surviving obj") forward_ptr = hdr.forward_ptr Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py Wed Oct 1 19:30:34 2008 @@ -804,7 +804,17 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass - root_stack_depth = 200 + root_stack_depth = 200 + +class TestMarkCompactGCGrowing(GenericMovingGCTests): + gcname = 'markcompact' + + class gcpolicy(gc.FrameworkGcPolicy): + class transformerclass(framework.FrameworkGCTransformer): + from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass + root_stack_depth = 200 + GC_PARAMS = {'space_size' : 128} + class TestGenerationGC(GenericMovingGCTests): gcname = "generation" From jlg at codespeak.net Wed Oct 1 21:30:14 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Wed, 1 Oct 2008 21:30:14 +0200 (CEST) Subject: [pypy-svn] r58540 - pypy/extradoc/sprintinfo/october-2008 Message-ID: <20081001193014.C5840169FA4@codespeak.net> Author: jlg Date: Wed Oct 1 21:30:13 2008 New Revision: 58540 Modified: pypy/extradoc/sprintinfo/october-2008/people.txt Log: J. Gustak attending october sprint Modified: pypy/extradoc/sprintinfo/october-2008/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/october-2008/people.txt (original) +++ pypy/extradoc/sprintinfo/october-2008/people.txt Wed Oct 1 21:30:13 2008 @@ -18,6 +18,7 @@ Alexander Schremmer 5-15 possible Samuele Pedroni 5-13 Hotel Blaettler Anders Hammarqvist 5-13 Hotel Blaettler +Jakub Gustak 6-9 ??? ==================== ============== ============================ People on the following list were present at previous sprints: From xoraxax at codespeak.net Thu Oct 2 00:10:09 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 2 Oct 2008 00:10:09 +0200 (CEST) Subject: [pypy-svn] r58544 - pypy/build/doc Message-ID: <20081001221009.0A7CA169FD1@codespeak.net> Author: xoraxax Date: Thu Oct 2 00:10:09 2008 New Revision: 58544 Modified: pypy/build/doc/benchmark_memory.txt Log: My ideas and new tools/urls -- mackall provides a linux patchset for better page mapping info, exmap provides interesting information. Modified: pypy/build/doc/benchmark_memory.txt ============================================================================== --- pypy/build/doc/benchmark_memory.txt (original) +++ pypy/build/doc/benchmark_memory.txt Thu Oct 2 00:10:09 2008 @@ -113,6 +113,12 @@ swapping. When Y and Z agree, we found a good way to measure memory usage. + xoraxax: doesnt that depend a lot of the runtime memory accesses of the + other processes and reproducible algorithms in the VM wrt. paging + decisions? E.g. in one scenario the VM could decide to page out + data to the swapfile while in another case it could just unmap + .text pages + Understanding linux /proc/pid/smaps info ------------------------------------------- @@ -289,3 +295,12 @@ XXX discuss and write toolchain +Exmap can be used to see very useful statistics about processes +including very precise shared RSS figures. It can also show +whether a specific symbol is mapped into the RAM but this +does not seem to be precise in xorAxAx's tests as the information +seems to be invariant to e.g. the usage of unicodedata. + +http://lwn.net/Articles/230975/ presents some ideas and a set +of patches for more precise page mapping information by +matt mackall From xoraxax at codespeak.net Thu Oct 2 00:12:16 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 2 Oct 2008 00:12:16 +0200 (CEST) Subject: [pypy-svn] r58545 - pypy/build/doc Message-ID: <20081001221216.386DD169FD1@codespeak.net> Author: xoraxax Date: Thu Oct 2 00:12:15 2008 New Revision: 58545 Modified: pypy/build/doc/benchmark_memory.txt Log: Added urls Modified: pypy/build/doc/benchmark_memory.txt ============================================================================== --- pypy/build/doc/benchmark_memory.txt (original) +++ pypy/build/doc/benchmark_memory.txt Thu Oct 2 00:12:15 2008 @@ -300,6 +300,8 @@ whether a specific symbol is mapped into the RAM but this does not seem to be precise in xorAxAx's tests as the information seems to be invariant to e.g. the usage of unicodedata. +http://labs.o-hand.com/exmap-console/ for embedded devices +http://www.berthels.co.uk/exmap/ for the main tool http://lwn.net/Articles/230975/ presents some ideas and a set of patches for more precise page mapping information by From hpk at codespeak.net Thu Oct 2 08:31:14 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 2 Oct 2008 08:31:14 +0200 (CEST) Subject: [pypy-svn] r58546 - pypy/extradoc/sprintinfo/october-2008 Message-ID: <20081002063114.6161E169FF8@codespeak.net> Author: hpk Date: Thu Oct 2 08:31:12 2008 New Revision: 58546 Modified: pypy/extradoc/sprintinfo/october-2008/people.txt Log: booked my room, 39 euro per night with wlan and free public transport. Modified: pypy/extradoc/sprintinfo/october-2008/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/october-2008/people.txt (original) +++ pypy/extradoc/sprintinfo/october-2008/people.txt Thu Oct 2 08:31:12 2008 @@ -10,10 +10,9 @@ Name Arrive/Depart Accomodation ==================== ============== ============================ Antonio Cuni 2-sys.maxint private -Holger Krekel 5-13th interested in sharing room +Holger Krekel 5-13th Hotel Schumann Maciej Fijalkowski 5-15 possible ??? Armin Rigo 3-inf private -Samuele Pedroni Carl Friedrich Bolz 3rd Oct - ??? my flat Alexander Schremmer 5-15 possible Samuele Pedroni 5-13 Hotel Blaettler From arigo at codespeak.net Thu Oct 2 09:46:43 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 2 Oct 2008 09:46:43 +0200 (CEST) Subject: [pypy-svn] r58547 - in pypy/dist/pypy/tool: . test Message-ID: <20081002074643.62367169ECA@codespeak.net> Author: arigo Date: Thu Oct 2 09:46:41 2008 New Revision: 58547 Modified: pypy/dist/pypy/tool/test/test_udir.py pypy/dist/pypy/tool/udir.py Log: Improve and document and test environment variables that control where the udir is created. That might (possibly) make packagers more happy. Modified: pypy/dist/pypy/tool/test/test_udir.py ============================================================================== --- pypy/dist/pypy/tool/test/test_udir.py (original) +++ pypy/dist/pypy/tool/test/test_udir.py Thu Oct 2 09:46:41 2008 @@ -1,8 +1,32 @@ from pypy.tool import udir -def test_udir(): +def test_svn_info(): res = udir.svn_info('http://codespeak.net/svn/pypy/dist/pypy/tool') assert res == 'dist' res = udir.svn_info('http://codespeak.net/svn/pypy/branch/stuff/pypy/tool') assert res == 'stuff' + +def test_make_udir(): + root = str(udir.udir.ensure('make_udir', dir=1)) + p1 = udir.make_udir(dir=root) + p2 = udir.make_udir(dir=root) + assert p1.relto(root).startswith('usession-') + assert p2.relto(root).startswith('usession-') + assert p1.basename.endswith('-0') + assert p2.basename.endswith('-1') + +def test_make_udir_with_basename(): + root = str(udir.udir.ensure('make_udir', dir=1)) + p1 = udir.make_udir(dir=root, basename='foobar') + assert p1.relto(root) == 'usession-foobar-0' + p1 = udir.make_udir(dir=root, basename='-foobar') + assert p1.relto(root) == 'usession-foobar-1' + p1 = udir.make_udir(dir=root, basename='foobar-') + assert p1.relto(root) == 'usession-foobar-2' + p1 = udir.make_udir(dir=root, basename='-foobar-') + assert p1.relto(root) == 'usession-foobar-3' + p1 = udir.make_udir(dir=root, basename='') + assert p1.relto(root) == 'usession-0' + p1 = udir.make_udir(dir=root, basename='-') + assert p1.relto(root) == 'usession-1' Modified: pypy/dist/pypy/tool/udir.py ============================================================================== --- pypy/dist/pypy/tool/udir.py (original) +++ pypy/dist/pypy/tool/udir.py Thu Oct 2 09:46:41 2008 @@ -3,6 +3,19 @@ # This uses the py lib's logic to create numbered directories. The last # three temporary directories are kept. # +# The udir is created with the following name: +# +# $PYPY_USESSION_DIR/usession-$PYPY_USESSION_BASENAME-N +# +# where N is a small number. If supported, a symlink is created for +# convenience too, pointing to (the most recent) udir: +# +# $PYPY_USESSION_DIR/usession-$PYPY_USESSION_BASENAME-$USER +# +# The default value for $PYPY_USESSION_DIR is the system tmp. +# The default value for $PYPY_USESSION_BASENAME is the name +# of the current subversion branch. +# import autopath import os @@ -17,11 +30,22 @@ else: return basename.split('/')[-2] -basename = os.environ.get('PYPY_USESSION_BASENAME') -if not basename: - try: - basename = '-' + svn_info(py.path.svnwc(py.magic.autopath().dirpath()).info().url) + '-' - except: - basename = '-' +def make_udir(dir=None, basename=None): + if dir is not None: + dir = local(dir) + if basename is None: + try: + p = py.magic.autopath().dirpath() + basename = svn_info(py.path.svnwc(p).info().url) + except: + basename = '' + if not basename.startswith('-'): + basename = '-' + basename + if not basename.endswith('-'): + basename = basename + '-' + return local.make_numbered_dir(rootdir = dir, + prefix = 'usession' + basename, + keep = 3) -udir = local.make_numbered_dir(prefix='usession' + basename, keep=3) +udir = make_udir(dir = os.environ.get('PYPY_USESSION_DIR'), + basename = os.environ.get('PYPY_USESSION_BASENAME')) From fijal at codespeak.net Thu Oct 2 11:28:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 11:28:33 +0200 (CEST) Subject: [pypy-svn] r58557 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081002092833.74FB816A087@codespeak.net> Author: fijal Date: Thu Oct 2 11:28:31 2008 New Revision: 58557 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py Log: Kill some dead code and make space smaller by default (this makes test_gc pass) Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Thu Oct 2 11:28:31 2008 @@ -57,7 +57,7 @@ inline_simple_malloc = True inline_simple_malloc_varsize = True - def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=2*(1024**2)): + def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096): self.space_size = space_size MovingGCBase.__init__(self, chunk_size) @@ -301,11 +301,7 @@ forward_ptr = hdr.forward_ptr hdr.forward_ptr = NULL hdr.tid &= ~(GCFLAG_MARKBIT|GCFLAG_FINALIZATION_ORDERING) - #llop.debug_print(lltype.Void, fromaddr, "copied to", forward_ptr, - # "\ntid", self.header(obj).tid, - # "\nsize", totalsize) llmemory.raw_memmove(fromaddr, forward_ptr, totalsize) - #llarena.arena_reset(fromaddr, totalsize, False) fromaddr += totalsize def debug_check_object(self, obj): Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py Thu Oct 2 11:28:31 2008 @@ -508,7 +508,6 @@ self.finalizer_lock_count += 1 try: while self.run_finalizers.non_empty(): - #print "finalizer" if self.finalizer_lock_count > 1: # the outer invocation of execute_finalizers() will do it break From fijal at codespeak.net Thu Oct 2 12:24:19 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 12:24:19 +0200 (CEST) Subject: [pypy-svn] r58560 - pypy/branch/gc-experiments/pypy/rpython/memory/test Message-ID: <20081002102419.173A516A087@codespeak.net> Author: fijal Date: Thu Oct 2 12:24:16 2008 New Revision: 58560 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py Log: Couple of additional prints Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_transformed_gc.py Thu Oct 2 12:24:16 2008 @@ -341,6 +341,7 @@ b = B() b.nextid = 1 b.num_deleted = 0 + b.num_deleted_c = 0 class A(object): def __init__(self): self.id = b.nextid @@ -353,6 +354,7 @@ class C(A): def __del__(self): b.num_deleted += 1 + b.num_deleted_c += 1 def f(x, y): persistent_a1 = A() persistent_a2 = A() @@ -365,6 +367,7 @@ llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) b.bla = persistent_a1.id + persistent_a2.id + persistent_a3.id + persistent_a4.id + print b.num_deleted_c return b.num_deleted run = self.runner(f, nbargs=2) # runs collect recursively 4 times @@ -804,18 +807,9 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass + GC_PARAMS = {'space_size': 2048} root_stack_depth = 200 -class TestMarkCompactGCGrowing(GenericMovingGCTests): - gcname = 'markcompact' - - class gcpolicy(gc.FrameworkGcPolicy): - class transformerclass(framework.FrameworkGCTransformer): - from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass - root_stack_depth = 200 - GC_PARAMS = {'space_size' : 128} - - class TestGenerationGC(GenericMovingGCTests): gcname = "generation" From fijal at codespeak.net Thu Oct 2 12:25:21 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 12:25:21 +0200 (CEST) Subject: [pypy-svn] r58561 - pypy/branch/gc-experiments/pypy/rpython/memory/test Message-ID: <20081002102521.7BDB816A087@codespeak.net> Author: fijal Date: Thu Oct 2 12:25:21 2008 New Revision: 58561 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Log: This test is as good here as in test_transformed_gc, but easier to debug. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Thu Oct 2 12:25:21 2008 @@ -318,6 +318,44 @@ res = self.interpret(f, [500]) assert res == 1 + 500 + + def test_collect_during_collect(self): + class B(object): + pass + b = B() + b.nextid = 1 + b.num_deleted = 0 + b.num_deleted_c = 0 + class A(object): + def __init__(self): + self.id = b.nextid + b.nextid += 1 + def __del__(self): + llop.gc__collect(lltype.Void) + b.num_deleted += 1 + C() + C() + class C(A): + def __del__(self): + b.num_deleted += 1 + b.num_deleted_c += 1 + def f(x, y): + persistent_a1 = A() + persistent_a2 = A() + i = 0 + while i < x: + i += 1 + a = A() + persistent_a3 = A() + persistent_a4 = A() + llop.gc__collect(lltype.Void) + llop.gc__collect(lltype.Void) + b.bla = persistent_a1.id + persistent_a2.id + persistent_a3.id + persistent_a4.id + print b.num_deleted_c + return b.num_deleted + res = self.interpret(f, [4, 42]) + assert res == 12 + def test_weakref_across_minor_collection(self): import weakref class A: From fijal at codespeak.net Thu Oct 2 12:36:12 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 12:36:12 +0200 (CEST) Subject: [pypy-svn] r58562 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081002103612.0611F16A0B1@codespeak.net> Author: fijal Date: Thu Oct 2 12:36:12 2008 New Revision: 58562 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Bugfixes Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Thu Oct 2 12:36:12 2008 @@ -160,16 +160,19 @@ self.markcompactcollect() def markcompactcollect(self, resizing=False): + llop.debug_print(lltype.Void, "Collecting") self.debug_check_consistency() if resizing: toaddr = self.tospace else: toaddr = llarena.arena_new_view(self.space) self.to_see = self.AddressStack() + self.mark_roots_recursively() if (self.objects_with_finalizers.non_empty() or self.run_finalizers.non_empty()): self.mark_objects_with_finalizers() - self.mark_roots_recursively() + self._trace_and_mark() + self.to_see.delete() finaladdr = self.update_forward_pointers(toaddr) if self.run_finalizers.non_empty(): self.update_run_finalizers() @@ -191,7 +194,14 @@ while self.run_finalizers.non_empty(): obj = self.run_finalizers.popleft() run_finalizers.append(self.get_forwarding_address(obj)) + self.run_finalizers.delete() self.run_finalizers = run_finalizers + objects_with_finalizers = self.AddressDeque() + while self.objects_with_finalizers.non_empty(): + obj = self.objects_with_finalizers.popleft() + objects_with_finalizers.append(self.get_forwarding_address(obj)) + self.objects_with_finalizers.delete() + self.objects_with_finalizers = objects_with_finalizers def get_type_id(self, addr): return self.header(addr).tid & TYPEID_MASK @@ -201,10 +211,12 @@ MarkCompactGC._mark_root_recursively, # stack roots MarkCompactGC._mark_root_recursively, # static in prebuilt non-gc structures MarkCompactGC._mark_root_recursively) # static in prebuilt gc objects + self._trace_and_mark() + + def _trace_and_mark(self): while self.to_see.non_empty(): obj = self.to_see.pop() self.trace(obj, self._mark_obj, None) - self.to_see.delete() def _mark_obj(self, pointer, ignored): obj = pointer.address[0] From fijal at codespeak.net Thu Oct 2 12:44:42 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 12:44:42 +0200 (CEST) Subject: [pypy-svn] r58564 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081002104442.F1E0E16A077@codespeak.net> Author: fijal Date: Thu Oct 2 12:44:40 2008 New Revision: 58564 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: kill debug print as well Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Thu Oct 2 12:44:40 2008 @@ -160,7 +160,6 @@ self.markcompactcollect() def markcompactcollect(self, resizing=False): - llop.debug_print(lltype.Void, "Collecting") self.debug_check_consistency() if resizing: toaddr = self.tospace From fijal at codespeak.net Thu Oct 2 13:08:23 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 13:08:23 +0200 (CEST) Subject: [pypy-svn] r58565 - pypy/branch/gc-experiments/pypy/translator/c/test Message-ID: <20081002110823.9BF1B16A07A@codespeak.net> Author: fijal Date: Thu Oct 2 13:08:23 2008 New Revision: 58565 Modified: pypy/branch/gc-experiments/pypy/translator/c/test/test_newgc.py Log: Add markcompact tests here Modified: pypy/branch/gc-experiments/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/translator/c/test/test_newgc.py (original) +++ pypy/branch/gc-experiments/pypy/translator/c/test/test_newgc.py Thu Oct 2 13:08:23 2008 @@ -1028,3 +1028,13 @@ def test_gc_set_max_heap_size(self): py.test.skip("not implemented") + +class TestMarkCompactGC(TestSemiSpaceGC): + gcpolicy = "markcompact" + should_be_moving = True + + def test_gc_set_max_heap_size(self): + py.test.skip("not implemented") + + def test_finalizer_order(self): + py.test.skip("not implemented") From hpk at codespeak.net Thu Oct 2 15:13:12 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 2 Oct 2008 15:13:12 +0200 (CEST) Subject: [pypy-svn] r58566 - pypy/dist/pypy/doc Message-ID: <20081002131312.2FFE516A0E2@codespeak.net> Author: hpk Date: Thu Oct 2 15:13:10 2008 New Revision: 58566 Modified: pypy/dist/pypy/doc/maemo.txt Log: documenting how i got to a scratchbox/maemo environment and built pypy-c. Modified: pypy/dist/pypy/doc/maemo.txt ============================================================================== --- pypy/dist/pypy/doc/maemo.txt (original) +++ pypy/dist/pypy/doc/maemo.txt Thu Oct 2 15:13:10 2008 @@ -1,15 +1,20 @@ How to run PyPy on top of maemo platform ======================================== +XXX this document needs cleanup, contains duplicate information, will need cleanup + after experiments yielded the best way to do pypy-c translations. + This is a short introduction how to install correct environment and cross-compile pypy to maemo platform emulator under qemu. Note that this is work-in-progress. -Installing `scratchbox`_ ------------------------- +variant 1: Installing `scratchbox`_ +------------------------------------------- I had no success with installing scratchbox 2.0, but theoretically it -should work. Follow these `installation instructions`_, +should work. + +Follow these `installation instructions`_ for 1.0, make sure that you install cpu-transparency modules, otherwise emulation will not be available. Preferred toolchain is cs2005q3.2-glibc2.5-arm. @@ -31,9 +36,8 @@ without the ``fakeroot``. It's quite a mess but in the end I get a ``python2.5``. - -Translating pypy ----------------- +cross-compiling pypy ++++++++++++++++++++++++++++ Run:: ./translate.py --platform=maemo --opt=mem targetpypystandalone --no-allworkingmodules @@ -43,5 +47,67 @@ from inside scratchbox. Default is /scratchbox/users//home/ where is your user id. + +variant 2: using official maemo-installs +---------------------------------------------------------------- + +the following taken mostly from + + http://yankandpaste.blogspot.com/2008/08/maemo-diablo-sdk-install-on-ubuntu-804.html + +1. On ubuntu linux edit sysctl.conf to contain:: + + vm.vdso_enabled = 0 + vm.mmap_min_addr = 4096 + + and activate via "sysctl -p". (on some linuxes this might crash your computer) + This step is neccessary for getting a working scratchbox installation. + +2. Grab http://repository.maemo.org/stable/diablo/maemo-scratchbox-install_4.1.1.sh + and run it as root with "sh maemo-scratchbox-install_4.1.1.sh -u USERNAME" + so that you automatically get an account created within the virtual scratchbox + environment. After this step you should be able to perform ``/scratchbox/login`` + and get a funny prompt. + +3. Grab http://repository.maemo.org/stable/diablo/maemo-sdk-install_4.1.1.sh + and run it. For me only selecting "[x] runtime environment" worked whereas + installing the dev packages failed but that might have been a (reproducible + though) local download problem. After this step you should be able + to perform ``/scratchbox/login`` and land in a DIABLO_ARM target environment, + the code name for current Maemo. You should be able to execute "python2.5" + within the scratchbox environment. + +4. It might not be neccessary in your installation but in order to get + the scratchbox and python to work without strange warnings i found + a note that it helps to setup the newest qemu-arm compiler. + For this you need to svn-checkout + + http://qemu-arm-eabi.svn.sourceforge.net/svnroot/qemu-arm-eabi/trunk + + and follow the README. (a number of steps). + +Compiling within scratchbox +++++++++++++++++++++++++++++++++ + +After switching to the virtual environment via ``/scratchbox/login`` +and commands like this:: + + svn co http://codespeak.net/svn/pypy/dist pypy-dist + cd pypy-dist/pypy/translator/goal + python translate.py --batch --opt=mem targetpypystandalone.py --no-allworkingmodules + +one will get (after around 10 hours on a medium intel machine) a working pypy-c. +You can transfer this binary to a real device an compile it there. + +cross-compiling (using scratchbox) +++++++++++++++++++++++++++++++++++++++++++++ + +XXX under investigation. might turn out that a different installation +method suffices. the above is still good for getting a maemo simulation +environment - not much missing to also get a simulated graphical environment +from it. + + + .. _`installation instructions`: http://www.scratchbox.org/documentation/user/scratchbox-1.0/html/installdoc.html .. _`scratchbox`: http://scratchbox.org From witulski at codespeak.net Thu Oct 2 16:01:48 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Thu, 2 Oct 2008 16:01:48 +0200 (CEST) Subject: [pypy-svn] r58568 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081002140148.1631216A0F0@codespeak.net> Author: witulski Date: Thu Oct 2 16:01:47 2008 New Revision: 58568 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py Log: CMP,JNE,JMP works Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Thu Oct 2 16:01:47 2008 @@ -31,7 +31,7 @@ # the memory. The parameters are overwritten # if one of the operands is an register. # tttn isn't used yet -# extra is an extra byte for long opcodes like IMUL +# extra is an extra byte for long opcodes(starting with 0F) like IMUL def make_two_operand_instr(W = None, R = None, X = None, B = None, opcode =None, m = None, md1 = None, md2 = None, tttn = None, extra = None): def quadreg_instr(self, arg1, arg2): # move the parameter @@ -45,7 +45,7 @@ rexB = B # TODO: other cases e.g memory as operand if isinstance(arg1,Register64): - rexR, modrm1 = self.get_register_bits(arg1.reg) + rexB, modrm1 = self.get_register_bits(arg1.reg) elif isinstance(arg1,Register8): modrm1 = self.get_register_bits_8Bit(arg1.reg) @@ -54,7 +54,7 @@ # e.g: IMUL (source==dest) if(modrm2=="sameReg"): modrm2 = modrm1 - rexB = rexR + rexR = rexB self.write_rex_byte(rexW, rexR, rexX, rexB) self.write(opcode) self.write_modRM_byte(3, modrm2, modrm1) @@ -65,9 +65,9 @@ self.write_modRM_byte(3, modrm2, modrm1) self.write(chr(arg2.value)) elif isinstance(arg2,Register64): - rexB, modrm2 = self.get_register_bits(arg2.reg) + rexR, modrm2 = self.get_register_bits(arg2.reg) # FIXME: exchange the two arguments (rexB/rexR) - self.write_rex_byte(rexW, rexB, rexX, rexR) + self.write_rex_byte(rexW, rexR, rexX, rexB) self.write(opcode) # used in imul (extra long opcode) if not extra == None: @@ -123,7 +123,6 @@ if isinstance(arg1,Register64): rexB, modrm1 = self.get_register_bits(arg1.reg) - # exchange the two arguments (modrm2/modrm1) if isinstance(arg2,Immediate64): new_opcode = hex(int(opcode,16)+modrm1) assert len(new_opcode[2:len(new_opcode)]) == 2 @@ -260,14 +259,15 @@ # op1 must be a register def JMP(self,op1): - method = getattr(self, "_JMP"+op1.to_string()) - method(op1) - #self.write("\xE9") - #self.writeImm32(displ) + #method = getattr(self, "_JMP"+op1.to_string()) + #method(op1) + print hex(self.tell()),": JMP to",hex(self.tell()+op1) + self.write("\xE9") + self.writeImm32(op1) # op1 is and 32bit displ def JNE(self,op1): - print hex(self.tell()),": JNE to",hex(op1) + print hex(self.tell()),": JNE to",hex(self.tell()+op1) self.write("\x0F") self.write("\x85") self.writeImm32(op1) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py Thu Oct 2 16:01:47 2008 @@ -3,10 +3,15 @@ from pypy.jit.codegen.x86_64.assembler import X86_64CodeBuilder #from ri386 import I386CodeBuilder +#FIXME: name:i386 modname = 'pypy.jit.codegen.i386.codebuf_' + os.name memhandler = __import__(modname, globals(), locals(), ['__doc__']) PTR = memhandler.PTR +print "ALBATROS " + +class CodeBlockOverflow(Exception): + pass class InMemoryCodeBuilder(X86_64CodeBuilder): @@ -30,5 +35,7 @@ def tell(self): baseaddr = rffi.cast(lltype.Signed, self._data) return baseaddr + self._pos + + Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Thu Oct 2 16:01:47 2008 @@ -144,11 +144,14 @@ self.mc.XOR(gv_w, gv_w) self.mc.IDIV(gv_y) return gv_w + +# def op_int_invert(self, gv_x): +# return self.mc.NOT(gv_x) #FIXME: can only jump 32bit #FIXME: -6 displacement: the displ+ rip of next instr - def jump_if_true(self, gv_condition, args_for_jump_gv): + def jump_if_true(self, gv_condition, args_for_jump_gv): targetbuilder = Builder() self.mc.CMP(gv_condition, Immediate32(0)) displ = self.calc_32bit_displacement(self.mc.tell(),targetbuilder.mc.tell()) @@ -200,19 +203,25 @@ #self.mc.write("\xB8\x0F\x00\x00\x00") print hex(self.mc.tell()),": RET" self._open() - self.mc.MOV(Register64("rax"), gv_returnvar) + if not gv_returnvar == None:#check void return + self.mc.MOV(Register64("rax"), gv_returnvar) self.mc.RET() self._close() - + #FIXME: uses 32bit displ # if the label is greater than 32bit # it must be in a register - def finish_and_goto(self, outputargs_gv, target): - print hex(self.mc.tell()),": JMP to",hex(target.startaddr) + def finish_and_goto(self, outputargs_gv, target): self._open() - gv_x = self.allocate_register() - self.mc.MOV(gv_x,Immediate64(target.startaddr)) - self.mc.JMP(gv_x) + #gv_x = self.allocate_register() + #self.mc.MOV(gv_x,Immediate64(target.startaddr)) + #self.mc.JMP(gv_x) + + displ = self.calc_32bit_displacement(self.mc.tell(),target.startaddr) + self.mc.JMP(displ) + + #self.mc.RET() + self._close() def allocate_register(self, register=None): @@ -261,6 +270,7 @@ def newgraph(self, sigtoken, name): arg_tokens, res_token = sigtoken + #print "arg_tokens:",arg_tokens inputargs_gv = [] builder = Builder() # TODO: Builder._open() @@ -270,5 +280,5 @@ # fill the list with the correct registers inputargs_gv = [builder.allocate_register(register_list[i]) for i in range(len(arg_tokens))] - return builder,Immediate32(entrypoint), inputargs_gv + return builder,Immediate64(entrypoint), inputargs_gv Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Thu Oct 2 16:01:47 2008 @@ -23,12 +23,13 @@ return gv_push_pop #FIXME: Jumps ever (CMP BUG) +#TODO: result of ops def make_jne(rgenop): sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) builder, gv_jne, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "jne") builder.start_writing() gv_z = builder.genop2("int_gt", gv_x, gv_y) - builder.mc.CMP(gv_z, rgenop.genconst(1)) + builder.mc.CMP(gv_z, rgenop.genconst(1)) builder.mc.JNE(6) builder.genop1("int_inc",gv_y)#not executed if x<=y builder.genop1("int_inc",gv_y)#not executed if x<=y @@ -37,17 +38,17 @@ builder.end() return gv_jne -def make_jmp(rgenop): - sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) - builder, gv_jmp, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "jmp") +# x= x+ y-1 +def make_jmp(rgenop,a): + sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed], lltype.Signed)) + builder, gv_jmp, [gv_x] = rgenop.newgraph(sigtoken, "jmp") builder.start_writing() - gv_z = builder.genop2("int_add", gv_x, gv_y) + builder.genop1("int_inc",gv_x) builder.finish_and_goto("",Label(builder.mc.tell()+6, [], 0)) - gv_w = builder.genop2("int_add", gv_z, gv_y) - gv_v = builder.genop2("int_sub", gv_w, gv_x) - gv_a = builder.genop1("int_inc",gv_v) - gv_b = builder.genop1("int_inc",gv_a) - builder.finish_and_return(sigtoken, gv_a) + b=0 + for b in range(a): + builder.genop1("int_inc",gv_x) + builder.finish_and_return(sigtoken, gv_x) builder.end() return gv_jmp @@ -212,8 +213,7 @@ assert res == 1 def test_greater(self): - rgenop = self.RGenOp() - cmp_function = make_cmp(rgenop, "int_gt") + cmp_function = make_cmp(self.RGenOp(), "int_gt") fnptr = self.cast(cmp_function,2) res = fnptr(3,4) # 3>4? assert res == 0 # false @@ -227,8 +227,7 @@ assert res == 0 def test_less(self): - rgenop = self.RGenOp() - cmp_function = make_cmp(rgenop, "int_lt") + cmp_function = make_cmp(self.RGenOp(), "int_lt") fnptr = self.cast(cmp_function,2) res = fnptr(3,4) # 3<4? assert res == 1 # true @@ -242,8 +241,7 @@ assert res == 1 def test_less_or_equal(self): - rgenop = self.RGenOp() - cmp_function = make_cmp(rgenop, "int_le") + cmp_function = make_cmp(self.RGenOp(), "int_le") fnptr = self.cast(cmp_function,2) res = fnptr(3,4) # 3<=4? assert res == 1 # true @@ -259,8 +257,7 @@ assert res == 1 def test_greater_or_equal(self): - rgenop = self.RGenOp() - cmp_function = make_cmp(rgenop, "int_ge") + cmp_function = make_cmp(self.RGenOp(), "int_ge") fnptr = self.cast(cmp_function,2) res = fnptr(3,4) # 3>=4? assert res == 0 # false @@ -282,14 +279,13 @@ assert res == 0 def test__equal(self): - rgenop = self.RGenOp() - cmp_function = make_cmp(rgenop, "int_eq",42) + cmp_function = make_cmp(self.RGenOp(), "int_eq",42) fnptr = self.cast(cmp_function,1) res = fnptr(42) assert res == 1 res = fnptr(23) assert res == 0 - cmp_function = make_cmp(rgenop, "int_eq") + cmp_function = make_cmp(self.RGenOp(), "int_eq") fnptr = self.cast(cmp_function,2) res = fnptr(3,4) # 3==4? assert res == 0 # false @@ -313,8 +309,7 @@ assert res == 0 def test_not_equal(self): - rgenop = self.RGenOp() - cmp_function = make_cmp(rgenop, "int_ne") + cmp_function = make_cmp(self.RGenOp(), "int_ne") fnptr = self.cast(cmp_function,2) res = fnptr(3,4) # 3!=4? assert res == 1 # true @@ -328,8 +323,7 @@ assert res == 1 def test_int_and(self): - rgenop = self.RGenOp() - bool_function = make_bool_op(rgenop,"int_and") + bool_function = make_bool_op(self.RGenOp(),"int_and") fnptr = self.cast(bool_function,2) result = fnptr(1,1) assert result == 1 @@ -346,8 +340,7 @@ assert result == 0 def test_int_or(self): - rgenop = self.RGenOp() - bool_function = make_bool_op(rgenop,"int_or") + bool_function = make_bool_op(self.RGenOp(),"int_or") fnptr = self.cast(bool_function,2) result = fnptr(1,1) assert result == 1 @@ -364,8 +357,7 @@ assert result == 63 def test_int_xor(self): - rgenop = self.RGenOp() - bool_function = make_bool_op(rgenop,"int_xor") + bool_function = make_bool_op(self.RGenOp(),"int_xor") fnptr = self.cast(bool_function,2) result = fnptr(1,1) assert result == 0 @@ -406,9 +398,9 @@ assert result == 42 # if x>y: - # return y+1 + # return y+3 # else: - # return y+3 + # return y+1 def test_jne(self): jne_func = make_jne(self.RGenOp()) fnptr = self.cast(jne_func,2) @@ -416,18 +408,37 @@ assert result == 4 result = fnptr(1,4) assert result == 5 + result = fnptr(12,14) + assert result == 15 - #def test_jmp(self): - # jmp_function = make_jmp(self.RGenOp()) - # fnptr = self.cast(jmp_function,2) - # result = fnptr(1,2) - # assert result == 5 + def test_jmp(self): + jmp_function = make_jmp(self.RGenOp(),3) + fnptr = self.cast(jmp_function,1) + result = fnptr(0) + assert result == 2 + result = fnptr(-2) + assert result == 0 + jmp_function = make_jmp(self.RGenOp(),20) + fnptr = self.cast(jmp_function,1) + result = fnptr(4) + assert result == 23 + result = fnptr(23) + assert result == 42 def test_push_pop(self): pp_func = make_push_pop(self.RGenOp()) fnptr = self.cast(pp_func,1) result = fnptr(1) assert result == 1 + +# def test_invert(self): +# inv_function = make_one_op_instr(self.RGenOp(),"int_invert") +# fnptr = self.cast(inv_function,1) +# result = fnptr(0) +# assert result == 0 +# result = fnptr(1) +# assert result == -1 + test_switch_many_args_direct = skip test_directtesthelper_direct = skip @@ -482,6 +493,5 @@ test_fieldaccess = skip test_interior_access = skip test_interior_access_float = skip - test_void_return = skip test_demo_f1_direct = skip test_red_switch = skip \ No newline at end of file Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py Thu Oct 2 16:01:47 2008 @@ -171,5 +171,7 @@ builder.finish_and_return(token, genv_result) eight = fp(10) # 10-2 = 8 assert eight == 8 - print eight + num = fp(-2) + assert num == -4 + \ No newline at end of file From fijal at codespeak.net Thu Oct 2 16:12:50 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 16:12:50 +0200 (CEST) Subject: [pypy-svn] r58570 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081002141250.6F7A616A0E6@codespeak.net> Author: fijal Date: Thu Oct 2 16:12:49 2008 New Revision: 58570 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Argh! I'm stupid. In C memory is *not* cleared just because Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Thu Oct 2 16:12:49 2008 @@ -182,6 +182,8 @@ self.space = toaddr self.free = finaladdr self.top_of_space = toaddr + self.space_size + if not resizing: + llarena.arena_reset(self.free, self.top_of_space - self.free, True) self.debug_check_consistency() if not resizing: self.record_red_zone() @@ -312,6 +314,7 @@ forward_ptr = hdr.forward_ptr hdr.forward_ptr = NULL hdr.tid &= ~(GCFLAG_MARKBIT|GCFLAG_FINALIZATION_ORDERING) + #if fromaddr != forward_ptr: llmemory.raw_memmove(fromaddr, forward_ptr, totalsize) fromaddr += totalsize From fijal at codespeak.net Thu Oct 2 16:15:29 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 16:15:29 +0200 (CEST) Subject: [pypy-svn] r58571 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081002141529.1940B16A0F7@codespeak.net> Author: fijal Date: Thu Oct 2 16:15:28 2008 New Revision: 58571 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: shuffle a bit. Free old arena in case it resized Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Thu Oct 2 16:15:28 2008 @@ -179,11 +179,13 @@ self.invalidate_weakrefs() self.update_objects_with_id() self.compact(resizing) + if not resizing: + llarena.arena_reset(finaladdr, self.space_size, True) + else: + llarena.arena_free(self.space) self.space = toaddr self.free = finaladdr self.top_of_space = toaddr + self.space_size - if not resizing: - llarena.arena_reset(self.free, self.top_of_space - self.free, True) self.debug_check_consistency() if not resizing: self.record_red_zone() From fijal at codespeak.net Thu Oct 2 16:31:37 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 16:31:37 +0200 (CEST) Subject: [pypy-svn] r58573 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081002143137.226D016A0C6@codespeak.net> Author: fijal Date: Thu Oct 2 16:31:35 2008 New Revision: 58573 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Always run tests before checking in. Even trivial stuff. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Thu Oct 2 16:31:35 2008 @@ -9,6 +9,7 @@ from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.lltypesystem.lloperation import llop +from pypy.rlib.objectmodel import we_are_translated GCFLAG_MARKBIT = MovingGCBase.first_unused_gcflag @@ -180,9 +181,13 @@ self.update_objects_with_id() self.compact(resizing) if not resizing: - llarena.arena_reset(finaladdr, self.space_size, True) + size = toaddr + self.space_size - finaladdr + llarena.arena_reset(finaladdr, size, True) else: - llarena.arena_free(self.space) + if we_are_translated(): + # because we free stuff already in raw_memmove, we + # would get double free here. Let's free it anyway + llarena.arena_free(self.space) self.space = toaddr self.free = finaladdr self.top_of_space = toaddr + self.space_size From fijal at codespeak.net Thu Oct 2 17:24:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 17:24:33 +0200 (CEST) Subject: [pypy-svn] r58575 - pypy/branch/gc-experiments/pypy/rpython/memory/test Message-ID: <20081002152433.BE1C716A11B@codespeak.net> Author: fijal Date: Thu Oct 2 17:24:32 2008 New Revision: 58575 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Log: Test copied from test_newgc.py. Happily fails here as well Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Thu Oct 2 17:24:32 2008 @@ -9,7 +9,7 @@ from pypy.rpython.lltypesystem.rstr import STR from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.objectmodel import compute_unique_id +from pypy.rlib.objectmodel import compute_unique_id, keepalive_until_here def stdout_ignore_ll_functions(msg): @@ -479,6 +479,57 @@ assert self.interpret(f, []) == 2 + + def test_callback_with_collect(self): + from pypy.rlib.libffi import ffi_type_pointer, cast_type_to_ffitype,\ + CDLL, ffi_type_void, CallbackFuncPtr, ffi_type_sint + from pypy.rpython.lltypesystem import rffi, ll2ctypes + from pypy.rlib import rgc + import gc + slong = cast_type_to_ffitype(rffi.LONG) + + from pypy.rpython.lltypesystem.ll2ctypes import libc_name + + def callback(ll_args, ll_res, stuff): + gc.collect() + p_a1 = rffi.cast(rffi.VOIDPP, ll_args[0])[0] + p_a2 = rffi.cast(rffi.VOIDPP, ll_args[1])[0] + a1 = rffi.cast(rffi.INTP, p_a1)[0] + a2 = rffi.cast(rffi.INTP, p_a2)[0] + res = rffi.cast(rffi.INTP, ll_res) + if a1 > a2: + res[0] = 1 + else: + res[0] = -1 + + def f(): + libc = CDLL(libc_name) + qsort = libc.getpointer('qsort', [ffi_type_pointer, slong, + slong, ffi_type_pointer], + ffi_type_void) + + ptr = CallbackFuncPtr([ffi_type_pointer, ffi_type_pointer], + ffi_type_sint, callback) + + TP = rffi.CArray(rffi.INT) + to_sort = lltype.malloc(TP, 4, flavor='raw') + to_sort[0] = 4 + to_sort[1] = 3 + to_sort[2] = 1 + to_sort[3] = 2 + qsort.push_arg(rffi.cast(rffi.VOIDP, to_sort)) + qsort.push_arg(rffi.sizeof(rffi.INT)) + qsort.push_arg(4) + 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] + lltype.free(to_sort, flavor='raw') + keepalive_until_here(ptr) + return int(result) + + res = self.interpret(f, []) + assert res == 1 + class TestMarkSweepGC(GCTest): from pypy.rpython.memory.gc.marksweep import MarkSweepGC as GCClass From fijal at codespeak.net Thu Oct 2 22:43:56 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 22:43:56 +0200 (CEST) Subject: [pypy-svn] r58578 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081002204356.0D13F168476@codespeak.net> Author: fijal Date: Thu Oct 2 22:43:55 2008 New Revision: 58578 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Fix Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Thu Oct 2 22:43:55 2008 @@ -174,7 +174,8 @@ self._trace_and_mark() self.to_see.delete() finaladdr = self.update_forward_pointers(toaddr) - if self.run_finalizers.non_empty(): + if (self.run_finalizers.non_empty() or + self.objects_with_finalizers.non_empty()): self.update_run_finalizers() if self.objects_with_weakrefs.non_empty(): self.invalidate_weakrefs() From fijal at codespeak.net Thu Oct 2 22:44:42 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 2 Oct 2008 22:44:42 +0200 (CEST) Subject: [pypy-svn] r58579 - pypy/branch/gc-experiments/pypy/rpython/memory/test Message-ID: <20081002204442.00687168577@codespeak.net> Author: fijal Date: Thu Oct 2 22:44:41 2008 New Revision: 58579 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Log: Remove this test as it uses not-implemented features in lltypelayout Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Thu Oct 2 22:44:41 2008 @@ -479,57 +479,6 @@ assert self.interpret(f, []) == 2 - - def test_callback_with_collect(self): - from pypy.rlib.libffi import ffi_type_pointer, cast_type_to_ffitype,\ - CDLL, ffi_type_void, CallbackFuncPtr, ffi_type_sint - from pypy.rpython.lltypesystem import rffi, ll2ctypes - from pypy.rlib import rgc - import gc - slong = cast_type_to_ffitype(rffi.LONG) - - from pypy.rpython.lltypesystem.ll2ctypes import libc_name - - def callback(ll_args, ll_res, stuff): - gc.collect() - p_a1 = rffi.cast(rffi.VOIDPP, ll_args[0])[0] - p_a2 = rffi.cast(rffi.VOIDPP, ll_args[1])[0] - a1 = rffi.cast(rffi.INTP, p_a1)[0] - a2 = rffi.cast(rffi.INTP, p_a2)[0] - res = rffi.cast(rffi.INTP, ll_res) - if a1 > a2: - res[0] = 1 - else: - res[0] = -1 - - def f(): - libc = CDLL(libc_name) - qsort = libc.getpointer('qsort', [ffi_type_pointer, slong, - slong, ffi_type_pointer], - ffi_type_void) - - ptr = CallbackFuncPtr([ffi_type_pointer, ffi_type_pointer], - ffi_type_sint, callback) - - TP = rffi.CArray(rffi.INT) - to_sort = lltype.malloc(TP, 4, flavor='raw') - to_sort[0] = 4 - to_sort[1] = 3 - to_sort[2] = 1 - to_sort[3] = 2 - qsort.push_arg(rffi.cast(rffi.VOIDP, to_sort)) - qsort.push_arg(rffi.sizeof(rffi.INT)) - qsort.push_arg(4) - 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] - lltype.free(to_sort, flavor='raw') - keepalive_until_here(ptr) - return int(result) - - res = self.interpret(f, []) - assert res == 1 - class TestMarkSweepGC(GCTest): from pypy.rpython.memory.gc.marksweep import MarkSweepGC as GCClass From fijal at codespeak.net Fri Oct 3 00:05:54 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 3 Oct 2008 00:05:54 +0200 (CEST) Subject: [pypy-svn] r58581 - pypy/branch/gc-experiments/pypy/config Message-ID: <20081002220554.BD932169FD7@codespeak.net> Author: fijal Date: Fri Oct 3 00:05:53 2008 New Revision: 58581 Modified: pypy/branch/gc-experiments/pypy/config/translationoption.py Log: use markcompact for --opt=mem translations. Just for fun... Modified: pypy/branch/gc-experiments/pypy/config/translationoption.py ============================================================================== --- pypy/branch/gc-experiments/pypy/config/translationoption.py (original) +++ pypy/branch/gc-experiments/pypy/config/translationoption.py Fri Oct 3 00:05:53 2008 @@ -300,7 +300,7 @@ '0': 'boehm nobackendopt', '1': 'boehm lowinline', 'size': 'boehm lowinline remove_asserts', - 'mem': 'marksweep lowinline remove_asserts', + 'mem': 'markcompact lowinline remove_asserts', '2': 'hybrid extraopts', '3': 'hybrid extraopts remove_asserts', } From hpk at codespeak.net Fri Oct 3 13:11:31 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 3 Oct 2008 13:11:31 +0200 (CEST) Subject: [pypy-svn] r58586 - in pypy/dist/pypy: doc rlib Message-ID: <20081003111131.E21DD169F82@codespeak.net> Author: hpk Date: Fri Oct 3 13:11:29 2008 New Revision: 58586 Modified: pypy/dist/pypy/doc/maemo.txt pypy/dist/pypy/rlib/pyplatform.py Log: a write up of how i got a clean, controlable working cross-compilation environment. There might be better ways (i still hope we can reuse the Maemo-provided install scripts which i mentioned further down in the doc) but for now this provides a sane enough way to get a cross-compilation environment, i guess. Modified: pypy/dist/pypy/doc/maemo.txt ============================================================================== --- pypy/dist/pypy/doc/maemo.txt (original) +++ pypy/dist/pypy/doc/maemo.txt Fri Oct 3 13:11:29 2008 @@ -8,6 +8,122 @@ cross-compile pypy to maemo platform emulator under qemu. Note that this is work-in-progress. + +Variant 0: cross-compiling pypy-c +------------------------------------------ + +The basic idea is to install a scratchbox environment that emulates +a real ARM-based N810 device. One can then login to this virtual +environment and execute ARM binaries. Scratchbox also provides +compiler toolchains that allow to drive a compiler from the outside. +This is what we want for building pypy-c because most work happens +independently from the platform and we want this work to execute natively. +For all platform relevant details we need to consult the target environment +and use the cross-compiler. So now let's move on to install such an environment +and compiler. + +Note: the + + http://repository.maemo.org/stable/diablo/maemo-scratchbox-install_4.1.1.sh + +script is provided by the maemo team and would automate installation. +Unfortuantely it does not provide a working cross-compiler (XXX +mail to maintainers and see if there is an easy fix). + +creating a /scratchbox environment ++++++++++++++++++++++++++++++++++++++++++ + +The basic idea is to follow + + http://www.scratchbox.org/documentation/user/scratchbox-1.0/html/tutorial.htm# + +with tarballs that work for the N810/Maemo target. + +make yourself an empty ``work`` directory and get a +working set of tarballs, e.g. like this:: + + export GET='wget -c' + export URL='http://www.scratchbox.org/download/files/sbox-releases/apophis/tarball' + $GET $URL/scratchbox-core-1.0.11-i386.tar.gz + $GET $URL/scratchbox-libs-1.0.11-i386.tar.gz + $GET $URL/scratchbox-toolchain-cs2007q3-glibc2.5-arm7-1.0.8-6-i386.tar.gz + $GET $URL/scratchbox-devkit-cputransp-1.0.7-i386.tar.gz + $GET $URL/scratchbox-devkit-perl-1.0.4-i386.tar.gz # for autoconf + $GET $URL/scratchbox-devkit-svn-1.0-i386.tar.gz # for being able to checkout + #$GET $URL/scratchbox-devkit-debian-1.0.10-i386.tar.gz # to eventually get debian working + +unpack all those tarballs, e.g. like this:: + + for x in *.tar.gz ; do sudo tar zxvf $x; done + +now you should have a ``work/scratchbox`` directory containing your basic uninitialized +scratchbox environment. + +make a symlink to have scratchbox at the canonical location:: + + ln -s /path/to/work/sandbox /sandbox + +initilaize the scratchbox install (you should be fine with using default answers to any questions):: + + /scratchbox/run_me_first.sh + +NOTE, that this will implicitely start some services that generally are controlled via:: + + /scratchbox/sbin/sbox_ctrl stop|start + +So if you later want to play with multiple different scratchbox installations you should stop the services before moving them away. You can also try to link this script into your ``/etc/init.d/`` so that it automatically runs after a reboot. + +Now create a user:: + + /scratchbox/sbin/sbox_adduser USER yes + +the 'yes' means that the USER gets added to the sbox unix group, neccessary to login into the virtual environment. + + +Creating an target emulating N810/Maemo environment ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Now we instruct scratchbox to define a target suitable for emulating the N810/Maemo device:: + +Login to the virtual environment and invoke : + + /scratchbox/login + sb-menu + +this brings up an interactive menu, you need to *setup* a new target, +you may name it "ARMEL" and then you need to select + + compiler: cs2007q3-glibc2.5-arm7 + devkits: cputransp, perl, svn + cputransp: (select 'qemu-arm-0.8.2-sb2' when it asks later on) + +In theory, you should also be able to execute the following cmdline:: + + sb-conf setup armel --compiler=cs2007q3-glibc2.5-arm7 \ + --devkit=cputransp:perl:svn \ + --cputransp=qemu-arm-0.8.2-sb2 + +but this did not provide a complete environment for me (XXX try to fix). + +Congrats! If all worked well you should now be able to cross-compile C programs via: + + /scratchbox/compilers/cs2007q3-glibc2.5-arm7/bin/arm-none-linux-gnueabi-gcc + +and copy the binary result to the N810/Maemo device. You can also login to +the virtual environment and execute the ARM binary there. + +PyPy's translation tool chain tries to use this cross-compiler when +you specify ``--platform=maemo`` to the translate.py script. + +So you can now get yourself a copy of pypy (in the hosting, not the +virtual environment of course!) and do: + + python translate.py --batch --platform=maemo --opt=mem \ + targetpypystandalone.py --no-allworkingmodules + +copy the result to the device and run it. + + variant 1: Installing `scratchbox`_ ------------------------------------------- Modified: pypy/dist/pypy/rlib/pyplatform.py ============================================================================== --- pypy/dist/pypy/rlib/pyplatform.py (original) +++ pypy/dist/pypy/rlib/pyplatform.py Fri Oct 3 13:11:29 2008 @@ -27,7 +27,13 @@ class Maemo(Platform): def get_compiler(self): # XXX how to make this reliable??? - return '/scratchbox/compilers/cs2005q3.2-glibc-arm/bin/sbox-arm-linux-gcc' + for x in ( + '/scratchbox/compilers/cs2007q3-glibc2.5-arm7/bin/arm-none-linux-gnueabi-gcc', + '/scratchbox/compilers/cs2005q3.2-glibc-arm/bin/sbox-arm-linux-gcc', + ): + if py.path.local(x).check(): + return x + raise ValueError("could not find scratchbox cross-compiler") def execute(self, cmd): return py.process.cmdexec('/scratchbox/login ' + cmd) From hpk at codespeak.net Fri Oct 3 13:21:41 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 3 Oct 2008 13:21:41 +0200 (CEST) Subject: [pypy-svn] r58587 - pypy/build/benchmem/benchmark Message-ID: <20081003112141.3966616A098@codespeak.net> Author: hpk Date: Fri Oct 3 13:21:40 2008 New Revision: 58587 Modified: pypy/build/benchmem/benchmark/sizes.py Log: on the N810 the messages benchmark consumes far more than 128 MB, use less Modified: pypy/build/benchmem/benchmark/sizes.py ============================================================================== --- pypy/build/benchmem/benchmark/sizes.py (original) +++ pypy/build/benchmem/benchmark/sizes.py Fri Oct 3 13:21:40 2008 @@ -361,7 +361,7 @@ def bench_list_of_messages(iter1): x = [] - for i in range(iter1): + for i in range(iter1/10): # make block-looking 40-lines, 72-columns e-mails msg = Message() msg.set_payload(('%072d' % i) * 40) From xoraxax at codespeak.net Sat Oct 4 12:40:26 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 4 Oct 2008 12:40:26 +0200 (CEST) Subject: [pypy-svn] r58589 - pypy/build/doc Message-ID: <20081004104026.8CFD416A0E6@codespeak.net> Author: xoraxax Date: Sat Oct 4 12:40:25 2008 New Revision: 58589 Modified: pypy/build/doc/benchmark_memory.txt Log: Some ideas about static memory usage. Modified: pypy/build/doc/benchmark_memory.txt ============================================================================== --- pypy/build/doc/benchmark_memory.txt (original) +++ pypy/build/doc/benchmark_memory.txt Sat Oct 4 12:40:25 2008 @@ -306,3 +306,28 @@ http://lwn.net/Articles/230975/ presents some ideas and a set of patches for more precise page mapping information by matt mackall + + +Considerations about static memory usage +---------------------------------------- + +While languages like C guarantee locality of static global +data and code by their module systems, PyPy generates a lot +of functions and global data into various modules. One +question is whether the resulting binary of the CC still +provides locality of these structures. Imagine every +vtable of the compiler's ast nodes spread in the resulting +data segment -- a single bytecode compilation would load +the whole data segment into RAM. Similar problems might +be found with functions. + +One consequence is that reducing the static memory usage +of the executable might not lead to reduced memory usage +at runtime if the locality is good. Also increasing the locality +would help to reduce the runtime memory usage. + +In order to find out what kind of global data is created by +a translation of an RPython program, one could write a reftracker +like graph viewer page that recursively sums up the value sizes +and provides navigation to referenced container values. + From xoraxax at codespeak.net Sat Oct 4 13:20:39 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 4 Oct 2008 13:20:39 +0200 (CEST) Subject: [pypy-svn] r58590 - pypy/build/doc Message-ID: <20081004112039.0095116846B@codespeak.net> Author: xoraxax Date: Sat Oct 4 13:20:38 2008 New Revision: 58590 Modified: pypy/build/doc/benchmark_memory.txt Log: Ideas on how to report static memory usage. Modified: pypy/build/doc/benchmark_memory.txt ============================================================================== --- pypy/build/doc/benchmark_memory.txt (original) +++ pypy/build/doc/benchmark_memory.txt Sat Oct 4 13:20:38 2008 @@ -330,4 +330,7 @@ a translation of an RPython program, one could write a reftracker like graph viewer page that recursively sums up the value sizes and provides navigation to referenced container values. - +This information could also be generated in a report-like way +with grouping by RPython module ("please list the sums of the +size of the ll values involved in all prebuilt constants referenced +only by pypy.module.xx"). From fijal at codespeak.net Sat Oct 4 13:29:05 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 4 Oct 2008 13:29:05 +0200 (CEST) Subject: [pypy-svn] r58591 - pypy/extradoc/talk/pyconpl-2008 Message-ID: <20081004112905.DB2EC169EC6@codespeak.net> Author: fijal Date: Sat Oct 4 13:29:05 2008 New Revision: 58591 Added: pypy/extradoc/talk/pyconpl-2008/ pypy/extradoc/talk/pyconpl-2008/abstract.txt (contents, props changed) Log: Abstract for pycon pl (in polish!) Added: pypy/extradoc/talk/pyconpl-2008/abstract.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pyconpl-2008/abstract.txt Sat Oct 4 13:29:05 2008 @@ -0,0 +1,8 @@ +PyPy - nowe podejscie do tworzenia interpreterow. +================================================= + +W ciagu 45 minut zamierzam przedstawic podstawowa architekture +interpretera Pythona PyPy. Dlaczego postanowilismy stworzyc cos +dramatycznie innego od dotychczasowych interpreterow, sukcesy podejscia +i wyzwania. Bedzie tez pare slow o magicznym Just In Time compiler i jak +doprowadzic do tego zeby python stal sie szybkim jezykiem dynamicznym. From cami at codespeak.net Sat Oct 4 13:34:13 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Sat, 4 Oct 2008 13:34:13 +0200 (CEST) Subject: [pypy-svn] r58592 - in pypy/dist/pypy/lang/gameboy: . test Message-ID: <20081004113413.3C420169F16@codespeak.net> Author: cami Date: Sat Oct 4 13:34:12 2008 New Revision: 58592 Added: pypy/dist/pypy/lang/gameboy/cpu_register.py pypy/dist/pypy/lang/gameboy/test/test_cpu_register.py (props changed) - copied unchanged from r58454, pypy/dist/pypy/lang/gameboy/test/test_register.py Removed: pypy/dist/pypy/lang/gameboy/test/test_register.py Modified: pypy/dist/pypy/lang/gameboy/cpu.py pypy/dist/pypy/lang/gameboy/test/test_cpu_2.py pypy/dist/pypy/lang/gameboy/video.py pypy/dist/pypy/lang/gameboy/video_mode.py Log: added separate cpu_register module renamed test_register to test_cpu_register adapted video, test_video to the introduced separation Modified: pypy/dist/pypy/lang/gameboy/cpu.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/cpu.py (original) +++ pypy/dist/pypy/lang/gameboy/cpu.py Sat Oct 4 13:34:12 2008 @@ -2,6 +2,8 @@ from pypy.lang.gameboy import constants from pypy.lang.gameboy.ram import * from pypy.lang.gameboy.interrupt import * +from pypy.lang.gameboy.cpu_register import Register, DoubleRegister, \ + FlagRegister, ImmediatePseudoRegister import pdb # --------------------------------------------------------------------------- @@ -13,217 +15,7 @@ #else : # return value return (value ^ 0x80) - 128 -# --------------------------------------------------------------------------- - -class AbstractRegister(object): - def get(self, use_cycles=True): - return 0xFF - -class Register(AbstractRegister): - - def __init__(self, cpu, value=0): - assert isinstance(cpu, CPU) - self.reset_value = self.value = value - self.cpu = cpu - if value != 0: - self.set(value) - - def reset(self): - self.value = self.reset_value - - def set(self, value, use_cycles=True): - self.value = value & 0xFF - if use_cycles: - self.cpu.cycles -= 1 - - def get(self, use_cycles=True): - return self.value - - def add(self, value, use_cycles=True): - self.set(self.get(use_cycles)+value, use_cycles) - - def sub(self, value, use_cycles=True): - self.set(self.get(use_cycles)-value, use_cycles) - -#------------------------------------------------------------------------------ - -class DoubleRegister(AbstractRegister): - - def __init__(self, cpu, hi, lo, reset_value=0): - assert isinstance(cpu, CPU) - assert isinstance(lo, Register) - assert isinstance(hi, Register) - self.cpu = cpu - self.hi = hi - self.lo = lo - self.reset_value = reset_value - - def set(self, value, use_cycles=True): - value = value & 0xFFFF - self.set_hi(value >> 8, use_cycles) - self.set_lo(value & 0xFF, use_cycles) - if use_cycles: - self.cpu.cycles += 1 - - def set_hi_lo(self, hi, lo, use_cycles=True): - self.set_hi(hi, use_cycles) - self.set_lo(lo, use_cycles) - - def reset(self): - self.set(self.reset_value, use_cycles=False) - - def set_hi(self, hi=0, use_cycles=True): - self.hi.set(hi, use_cycles) - - def set_lo(self, lo=0, use_cycles=True): - self.lo.set(lo, use_cycles) - - def get(self, use_cycles=True): - return (self.hi.get(use_cycles)<<8) + self.lo.get(use_cycles) - - def get_hi(self, use_cycles=True): - return self.hi.get(use_cycles) - - def get_lo(self, use_cycles=True): - return self.lo.get(use_cycles) - - def inc(self, use_cycles=True): - self.set(self.get(use_cycles) +1, use_cycles=use_cycles) - if use_cycles: - self.cpu.cycles -= 1 - - def dec(self, use_cycles=True): - self.set(self.get(use_cycles) - 1, use_cycles=use_cycles) - if use_cycles: - self.cpu.cycles -= 1 - - def add(self, value, use_cycles=True): - self.set(self.get(use_cycles) + value, use_cycles=use_cycles) - if use_cycles: - self.cpu.cycles -= 2 - - -# ------------------------------------------------------------------------------ - -class ImmediatePseudoRegister(Register): - - def __init__(self, cpu, hl): - assert isinstance(cpu, CPU) - self.cpu = cpu - self.hl = hl - - def set(self, value, use_cycles=True): - self.cpu.write(self.hl.get(use_cycles=use_cycles), value) # 2 + 0 - if not use_cycles: - self.cpu.cycles += 2 - - def get(self, use_cycles=True): - if not use_cycles: - self.cpu.cycles += 1 - return self.cpu.read(self.hl.get(use_cycles=use_cycles)) # 1 - -# ------------------------------------------------------------------------------ - -class FlagRegister(Register): - """ - The Flag Register (lower 8bit of AF register) - Bit Name Set Clr Expl. - 7 zf Z NZ Zero Flag - 6 n - - Add/Sub-Flag (BCD) - 5 h - - Half Carry Flag (BCD) - 4 cy C NC Carry Flag - 3-0 - - - Not used (always zero) - Conatins the result from the recent instruction which has affected flags. - - The Zero Flag (Z) - This bit becomes set (1) if the result of an operation has been zero (0). - Used for conditional jumps. - - The Carry Flag (C, or Cy) - Becomes set when the result of an addition became bigger than FFh (8bit) or - FFFFh (16bit). Or when the result of a subtraction or comparision became - less than zero (much as for Z80 and 80x86 CPUs, but unlike as for 65XX and - ARM CPUs). Also the flag becomes set when a rotate/shift operation has - shifted-out a "1"-bit. - Used for conditional jumps, and for instructions such like ADC, SBC, RL, - RLA, etc. - - The BCD Flags (N, H) - These flags are (rarely) used for the DAA instruction only, N Indicates - whether the previous instruction has been an addition or subtraction, and H - indicates carry for lower 4bits of the result, also for DAA, the C flag must - indicate carry for upper 8bits. - After adding/subtracting two BCD numbers, DAA is intended to convert the - result into BCD format; BCD numbers are ranged from 00h to 99h rather than - 00h to FFh. - Because C and H flags must contain carry-outs for each digit, DAA cannot be - used for 16bit operations (which have 4 digits), or for INC/DEC operations - (which do not affect C-flag). - """ - def __init__(self, cpu, reset_value): - assert isinstance(cpu, CPU) - self.cpu = cpu - self.reset_value = reset_value - self.reset() - - def reset(self): - self.partial_reset() - - def partial_reset(self, keep_is_zero=False, keep_is_subtraction=False, - keep_is_half_carry=False, keep_is_carry=False,\ - keep_p=False, keep_s=False): - if not keep_is_zero: - self.is_zero = False - if not keep_is_subtraction: - self.is_subtraction = False - if not keep_is_half_carry: - self.is_half_carry = False - if not keep_is_carry: - self.is_carry = False - if not keep_p: - self.p_flag = False - if not keep_s: - self.s_flag = False - self.lower = 0x00 - - def get(self, use_cycles=True): - value = 0 - value += (int(self.is_carry) << 4) - value += (int(self.is_half_carry) << 5) - value += (int(self.is_subtraction) << 6) - value += (int(self.is_zero) << 7) - return value + self.lower - - def set(self, value, use_cycles=True): - self.is_carry = bool(value & (1 << 4)) - self.is_half_carry = bool(value & (1 << 5)) - self.is_subtraction = bool(value & (1 << 6)) - self.is_zero = bool(value & (1 << 7)) - self.lower = value & 0x0F - if use_cycles: - self.cpu.cycles -= 1 - - def zero_check(self, a, reset=False): - if reset: - self.reset() - if isinstance(a, (Register)): - a = a.get() - self.is_zero = ((a & 0xFF) == 0) - - def is_carry_compare(self, value, compare_and=0x01, reset=False): - if reset: - self.reset() - self.is_carry = ((value & compare_and) != 0) - - def is_half_carry_compare(self, value, a, inverted=False): - if inverted: - self.is_half_carry = ((value & 0x0F) < (a & 0x0F)) - else: - self.is_half_carry = ((value & 0x0F) > (a & 0x0F)) - - #def is_carry_compare(self, a, b): - # self.is_carry = (a < b) - + # # ------------------------------------------------------------------------------ Added: pypy/dist/pypy/lang/gameboy/cpu_register.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lang/gameboy/cpu_register.py Sat Oct 4 13:34:12 2008 @@ -0,0 +1,212 @@ + +# --------------------------------------------------------------------------- + +class AbstractRegister(object): + def get(self, use_cycles=True): + return 0xFF + +class Register(AbstractRegister): + + def __init__(self, cpu, value=0): + # assert isinstance(cpu, CPU) + self.reset_value = self.value = value + self.cpu = cpu + if value != 0: + self.set(value) + + def reset(self): + self.value = self.reset_value + + def set(self, value, use_cycles=True): + self.value = value & 0xFF + if use_cycles: + self.cpu.cycles -= 1 + + def get(self, use_cycles=True): + return self.value + + def add(self, value, use_cycles=True): + self.set(self.get(use_cycles)+value, use_cycles) + + def sub(self, value, use_cycles=True): + self.set(self.get(use_cycles)-value, use_cycles) + +#------------------------------------------------------------------------------ + +class DoubleRegister(AbstractRegister): + + def __init__(self, cpu, hi, lo, reset_value=0): + #assert isinstance(cpu, CPU) + #assert isinstance(lo, Register) + #assert isinstance(hi, Register) + self.cpu = cpu + self.hi = hi + self.lo = lo + self.reset_value = reset_value + + def set(self, value, use_cycles=True): + value = value & 0xFFFF + self.set_hi(value >> 8, use_cycles) + self.set_lo(value & 0xFF, use_cycles) + if use_cycles: + self.cpu.cycles += 1 + + def set_hi_lo(self, hi, lo, use_cycles=True): + self.set_hi(hi, use_cycles) + self.set_lo(lo, use_cycles) + + def reset(self): + self.set(self.reset_value, use_cycles=False) + + def set_hi(self, hi=0, use_cycles=True): + self.hi.set(hi, use_cycles) + + def set_lo(self, lo=0, use_cycles=True): + self.lo.set(lo, use_cycles) + + def get(self, use_cycles=True): + return (self.hi.get(use_cycles)<<8) + self.lo.get(use_cycles) + + def get_hi(self, use_cycles=True): + return self.hi.get(use_cycles) + + def get_lo(self, use_cycles=True): + return self.lo.get(use_cycles) + + def inc(self, use_cycles=True): + self.set(self.get(use_cycles) +1, use_cycles=use_cycles) + if use_cycles: + self.cpu.cycles -= 1 + + def dec(self, use_cycles=True): + self.set(self.get(use_cycles) - 1, use_cycles=use_cycles) + if use_cycles: + self.cpu.cycles -= 1 + + def add(self, value, use_cycles=True): + self.set(self.get(use_cycles) + value, use_cycles=use_cycles) + if use_cycles: + self.cpu.cycles -= 2 + + +# ------------------------------------------------------------------------------ + +class ImmediatePseudoRegister(Register): + + def __init__(self, cpu, hl): + #assert isinstance(cpu, CPU) + self.cpu = cpu + self.hl = hl + + def set(self, value, use_cycles=True): + self.cpu.write(self.hl.get(use_cycles=use_cycles), value) # 2 + 0 + if not use_cycles: + self.cpu.cycles += 2 + + def get(self, use_cycles=True): + if not use_cycles: + self.cpu.cycles += 1 + return self.cpu.read(self.hl.get(use_cycles=use_cycles)) # 1 + +# ------------------------------------------------------------------------------ + +class FlagRegister(Register): + """ + The Flag Register (lower 8bit of AF register) + Bit Name Set Clr Expl. + 7 zf Z NZ Zero Flag + 6 n - - Add/Sub-Flag (BCD) + 5 h - - Half Carry Flag (BCD) + 4 cy C NC Carry Flag + 3-0 - - - Not used (always zero) + Contains the result from the recent instruction which has affected flags. + + The Zero Flag (Z) + This bit becomes set (1) if the result of an operation has been zero (0). + Used for conditional jumps. + + The Carry Flag (C, or Cy) + Becomes set when the result of an addition became bigger than FFh (8bit) or + FFFFh (16bit). Or when the result of a subtraction or comparision became + less than zero (much as for Z80 and 80x86 CPUs, but unlike as for 65XX and + ARM CPUs). Also the flag becomes set when a rotate/shift operation has + shifted-out a "1"-bit. + Used for conditional jumps, and for instructions such like ADC, SBC, RL, + RLA, etc. + + The BCD Flags (N, H) + These flags are (rarely) used for the DAA instruction only, N Indicates + whether the previous instruction has been an addition or subtraction, and H + indicates carry for lower 4bits of the result, also for DAA, the C flag must + indicate carry for upper 8bits. + After adding/subtracting two BCD numbers, DAA is intended to convert the + result into BCD format; BCD numbers are ranged from 00h to 99h rather than + 00h to FFh. + Because C and H flags must contain carry-outs for each digit, DAA cannot be + used for 16bit operations (which have 4 digits), or for INC/DEC operations + (which do not affect C-flag). + """ + def __init__(self, cpu, reset_value): + #assert isinstance(cpu, CPU) + self.cpu = cpu + self.reset_value = reset_value + self.reset() + + def reset(self): + self.partial_reset() + + def partial_reset(self, keep_is_zero=False, keep_is_subtraction=False, + keep_is_half_carry=False, keep_is_carry=False,\ + keep_p=False, keep_s=False): + if not keep_is_zero: + self.is_zero = False + if not keep_is_subtraction: + self.is_subtraction = False + if not keep_is_half_carry: + self.is_half_carry = False + if not keep_is_carry: + self.is_carry = False + if not keep_p: + self.p_flag = False + if not keep_s: + self.s_flag = False + self.lower = 0x00 + + def get(self, use_cycles=True): + value = 0 + value += (int(self.is_carry) << 4) + value += (int(self.is_half_carry) << 5) + value += (int(self.is_subtraction) << 6) + value += (int(self.is_zero) << 7) + return value + self.lower + + def set(self, value, use_cycles=True): + self.is_carry = bool(value & (1 << 4)) + self.is_half_carry = bool(value & (1 << 5)) + self.is_subtraction = bool(value & (1 << 6)) + self.is_zero = bool(value & (1 << 7)) + self.lower = value & 0x0F + if use_cycles: + self.cpu.cycles -= 1 + + def zero_check(self, a, reset=False): + if reset: + self.reset() + if isinstance(a, (Register)): + a = a.get() + self.is_zero = ((a & 0xFF) == 0) + + def is_carry_compare(self, value, compare_and=0x01, reset=False): + if reset: + self.reset() + self.is_carry = ((value & compare_and) != 0) + + def is_half_carry_compare(self, value, a, inverted=False): + if inverted: + self.is_half_carry = ((value & 0x0F) < (a & 0x0F)) + else: + self.is_half_carry = ((value & 0x0F) > (a & 0x0F)) + + #def is_carry_compare(self, a, b): + # self.is_carry = (a < b) + \ No newline at end of file Modified: pypy/dist/pypy/lang/gameboy/test/test_cpu_2.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/test/test_cpu_2.py (original) +++ pypy/dist/pypy/lang/gameboy/test/test_cpu_2.py Sat Oct 4 13:34:12 2008 @@ -30,6 +30,8 @@ TEST_CPU.reset() return TEST_CPU +# ----------------------------------------------------------------------------- + def assert_default_registers(cpu, a=constants.RESET_A, bc=constants.RESET_BC,\ de=constants.RESET_DE, f=constants.RESET_F,\ hl=constants.RESET_HL, sp=constants.RESET_SP,\ @@ -38,19 +40,26 @@ def assert_registers(cpu, a=None, bc=None, de=None, f=None, hl=None, sp=None, pc=None): if a is not None: - assert cpu.a.get() == a, "Register a is %s but should be %s" % (hex(cpu.a.get()), hex(a)) + assert cpu.a.get() == a, \ + "Register a is %s but should be %s" % (hex(cpu.a.get()), hex(a)) if bc is not None: - assert cpu.bc.get() == bc, "Register bc is %s but should be %s" % (hex(cpu.bc.get()), hex(bc)) + assert cpu.bc.get() == bc, \ + "Register bc is %s but should be %s" % (hex(cpu.bc.get()), hex(bc)) if de is not None: - assert cpu.de.get() == de, "Register de is %s but should be %s" % (hex(cpu.de.get()),hex(de)) + assert cpu.de.get() == de, \ + "Register de is %s but should be %s" % (hex(cpu.de.get()),hex(de)) if f is not None: - assert cpu.flag.get() == f, "Register f is %s but should be %s" % (hex(cpu.flag.get()),hex(f)) + assert cpu.flag.get() == f, \ + "Register f is %s but should be %s" % (hex(cpu.flag.get()),hex(f)) if hl is not None: - assert cpu.hl.get() == hl, "Register hl is %s but should be %s" % (hex(cpu.hl.get()), hex(hl)) + assert cpu.hl.get() == hl, \ + "Register hl is %s but should be %s" % (hex(cpu.hl.get()), hex(hl)) if sp is not None: - assert cpu.sp.get() == sp, "Register sp is %s but should be %s" % (hex(cpu.sp.get()), hex(sp)) + assert cpu.sp.get() == sp, \ + "Register sp is %s but should be %s" % (hex(cpu.sp.get()), hex(sp)) if pc is not None: - assert cpu.pc.get() == pc, "Register pc is %s but should be %s" % (hex(cpu.pc.get()), hex(pc)) + assert cpu.pc.get() == pc, \ + "Register pc is %s but should be %s" % (hex(cpu.pc.get()), hex(pc)) def assert_defaults(cpu, z=True, n=False, h=False, c=False, p=False, s=False): @@ -58,17 +67,23 @@ def assert_flags(cpu, z=None, n=None, h=None, c=None, p=None, s=None): if z is not None: - assert cpu.flag.is_zero == z, "Z-Flag is %s but should be %s" % (cpu.flag.is_zero, z) + assert cpu.flag.is_zero == z, \ + "Z-Flag is %s but should be %s" % (cpu.flag.is_zero, z) if n is not None: - assert cpu.flag.is_subtraction == n, "N-Flag is %s but should be %s" % (cpu.flag.is_subtraction, n) + assert cpu.flag.is_subtraction == n, \ + "N-Flag is %s but should be %s" % (cpu.flag.is_subtraction, n) if h is not None: - assert cpu.flag.is_half_carry == h, "H-Flag is %s but should be %s" % (cpu.flag.is_half_carry, h) + assert cpu.flag.is_half_carry == h, \ + "H-Flag is %s but should be %s" % (cpu.flag.is_half_carry, h) if c is not None: - assert cpu.flag.is_carry == c, "C-Flag is %s but should be %s" % (cpu.flag.is_carry, c) + assert cpu.flag.is_carry == c, \ + "C-Flag is %s but should be %s" % (cpu.flag.is_carry, c) if p is not None: - assert cpu.flag.p_flag == p, "P-Flag is %s but should be %s" % (cpu.flag.p_flag, p) + assert cpu.flag.p_flag == p, \ + "P-Flag is %s but should be %s" % (cpu.flag.p_flag, p) if s is not None: - assert cpu.flag.s_flag == s, "S-Flag is %s but should be %s" % (cpu.flag.s_flag, s) + assert cpu.flag.s_flag == s, \ + "S-Flag is %s but should be %s" % (cpu.flag.s_flag, s) def prepare_for_double_fetch(cpu, value): prepare_for_fetch(cpu, (value & 0xFF00) >> 8, value & 0x00FF) Modified: pypy/dist/pypy/lang/gameboy/video.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/video.py (original) +++ pypy/dist/pypy/lang/gameboy/video.py Sat Oct 4 13:34:12 2008 @@ -461,6 +461,7 @@ if self.window.enabled: self.window.draw_line(self.line_y) if self.control.sprites_enabled: + #self.draw_sprites_line_new() self.draw_sprites_line() self.draw_pixels_line() @@ -499,6 +500,9 @@ """ return sprites.sort(key=operator.itemgetter("x")) + + # ----------------------------------------------- + def draw_sprites_line(self): count = self.scan_sprites() lastx = 176 Modified: pypy/dist/pypy/lang/gameboy/video_mode.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/video_mode.py (original) +++ pypy/dist/pypy/lang/gameboy/video_mode.py Sat Oct 4 13:34:12 2008 @@ -30,7 +30,7 @@ def id(self): raise Exception("unimplemented method") - def activate(self, previous_mode): + def activate(self): raise Exception("unimplemented method") def emulate(self): From xoraxax at codespeak.net Sat Oct 4 13:37:43 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 4 Oct 2008 13:37:43 +0200 (CEST) Subject: [pypy-svn] r58593 - pypy/extradoc/sprintinfo/october-2008 Message-ID: <20081004113743.0F0A5169ED9@codespeak.net> Author: xoraxax Date: Sat Oct 4 13:37:42 2008 New Revision: 58593 Modified: pypy/extradoc/sprintinfo/october-2008/people.txt Log: Updated accomodation info. Modified: pypy/extradoc/sprintinfo/october-2008/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/october-2008/people.txt (original) +++ pypy/extradoc/sprintinfo/october-2008/people.txt Sat Oct 4 13:37:42 2008 @@ -11,13 +11,13 @@ ==================== ============== ============================ Antonio Cuni 2-sys.maxint private Holger Krekel 5-13th Hotel Schumann -Maciej Fijalkowski 5-15 possible ??? +Maciej Fijalkowski 5-15 possible antos's flat Armin Rigo 3-inf private -Carl Friedrich Bolz 3rd Oct - ??? my flat -Alexander Schremmer 5-15 possible +Carl Friedrich Bolz 3rd Oct - ??? my flat +Alexander Schremmer 5-15 possible carl's flat Samuele Pedroni 5-13 Hotel Blaettler Anders Hammarqvist 5-13 Hotel Blaettler -Jakub Gustak 6-9 ??? +Jakub Gustak 6-9 carl's flat ==================== ============== ============================ People on the following list were present at previous sprints: From hpk at codespeak.net Sat Oct 4 13:39:55 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 4 Oct 2008 13:39:55 +0200 (CEST) Subject: [pypy-svn] r58594 - pypy/build/doc Message-ID: <20081004113955.4C1A3169F06@codespeak.net> Author: hpk Date: Sat Oct 4 13:39:54 2008 New Revision: 58594 Modified: pypy/build/doc/benchmark_memory.txt Log: some info on current benchmarking tools. Modified: pypy/build/doc/benchmark_memory.txt ============================================================================== --- pypy/build/doc/benchmark_memory.txt (original) +++ pypy/build/doc/benchmark_memory.txt Sat Oct 4 13:39:54 2008 @@ -4,11 +4,7 @@ $Id$ -XXX this is a draft incomplete document -XXX next step is to lay out and write -XXX the benchmarking infrastructure and -XXX to incrementally complete and update -XXX the document +XXX draft XXX what we want to measure =============================================== @@ -178,7 +174,7 @@ Let's see what changes if we do:: - >>> l = ["xasd"] * 1000000" + >>> l = ["xasd"] * 1000000 we get this new mapping in the python process:: @@ -293,8 +289,6 @@ http://maemo.org/development/tools/doc/diablo/sp-smaps-measure/ http://maemo.org/development/tools/doc/diablo/sp-memusage/ -XXX discuss and write toolchain - Exmap can be used to see very useful statistics about processes including very precise shared RSS figures. It can also show whether a specific symbol is mapped into the RAM but this @@ -307,6 +301,24 @@ of patches for more precise page mapping information by matt mackall +runbench.py / report.py +++++++++++++++++++++++++++++++++ + +At http://codespeak.net/svn/pypy/build/benchmem there +are linux scripts to measure memory usage of benchmarks +and generating a report from the results: + +* runbench.py runs the benchamrks in the ``benchmark`` + directory and writes information about memory usage + into ``bench.log``. One can specify multiple Python + Intepreters for execution of the benchmarks. + +* report.py takes a bench.log and generates a textual report. + +Current benchmarks: + +* ``sizes.py``: a number of benchmarks to create different + python objects Considerations about static memory usage ---------------------------------------- From arigo at codespeak.net Sat Oct 4 18:56:02 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 4 Oct 2008 18:56:02 +0200 (CEST) Subject: [pypy-svn] r58596 - pypy/extradoc/sprintinfo/october-2008 Message-ID: <20081004165602.22FAE16A18D@codespeak.net> Author: arigo Date: Sat Oct 4 18:55:59 2008 New Revision: 58596 Modified: pypy/extradoc/sprintinfo/october-2008/people.txt Log: Adding John. Modified: pypy/extradoc/sprintinfo/october-2008/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/october-2008/people.txt (original) +++ pypy/extradoc/sprintinfo/october-2008/people.txt Sat Oct 4 18:55:59 2008 @@ -18,6 +18,7 @@ Samuele Pedroni 5-13 Hotel Blaettler Anders Hammarqvist 5-13 Hotel Blaettler Jakub Gustak 6-9 carl's flat +John Witulski living there living there ==================== ============== ============================ People on the following list were present at previous sprints: From hpk at codespeak.net Sun Oct 5 08:36:00 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 5 Oct 2008 08:36:00 +0200 (CEST) Subject: [pypy-svn] r58599 - pypy/build/doc Message-ID: <20081005063600.4337416A05C@codespeak.net> Author: hpk Date: Sun Oct 5 08:35:59 2008 New Revision: 58599 Modified: pypy/build/doc/benchmark_memory.txt Log: adding links to papers Modified: pypy/build/doc/benchmark_memory.txt ============================================================================== --- pypy/build/doc/benchmark_memory.txt (original) +++ pypy/build/doc/benchmark_memory.txt Sun Oct 5 08:35:59 2008 @@ -346,3 +346,19 @@ with grouping by RPython module ("please list the sums of the size of the ll values involved in all prebuilt constants referenced only by pypy.module.xx"). + +GC related Papers and links +=================================== + +http://www-cs.canisius.edu/~hertzm/thesis.pdf +a GC with OS support that behaves well in context of swapping. + +http://portal.acm.org/citation.cfm?id=1070891.1065943 +An Energy Efficient Garbage Collector for Java Embedded Devices +(mark/compact + deferred ref counting) + +http://www.ibm.com/developerworks/ibm/library/i-incrcomp/ +"Hot to minimize pause times and free the heap from dark matter" + + + From hpk at codespeak.net Sun Oct 5 09:14:11 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 5 Oct 2008 09:14:11 +0200 (CEST) Subject: [pypy-svn] r58600 - in pypy/dist/pypy: config rlib translator/tool/test Message-ID: <20081005071411.D3EFE169FD9@codespeak.net> Author: hpk Date: Sun Oct 5 09:14:09 2008 New Revision: 58600 Modified: pypy/dist/pypy/config/translationoption.py pypy/dist/pypy/rlib/pyplatform.py pypy/dist/pypy/translator/tool/test/test_cbuild.py Log: simplifying handling of c compiler and fixing a problem with caching. Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Sun Oct 5 09:14:09 2008 @@ -346,19 +346,15 @@ ] def set_platform(config, platform): - from pypy.rlib.pyplatform import Platform, Maemo, OverloadCompilerPlatform + from pypy.rlib.pyplatform import Platform, Maemo from pypy.rlib import pyplatform from pypy.translator.tool.cbuild import ExternalCompilationInfo if isinstance(platform, str): if platform == 'maemo': - platform = Maemo() + platform = Maemo(cc=config.translation.cc or None) elif platform == 'host': return else: raise NotImplementedError('Platform = %s' % (platform,)) assert isinstance(platform, Platform) pyplatform.platform = platform - if config.translation.cc: - pyplatform.platform = OverloadCompilerPlatform(platform, - config.translation.cc) - Modified: pypy/dist/pypy/rlib/pyplatform.py ============================================================================== --- pypy/dist/pypy/rlib/pyplatform.py (original) +++ pypy/dist/pypy/rlib/pyplatform.py Sun Oct 5 09:14:09 2008 @@ -1,13 +1,19 @@ """ This file contains various platform-specific profiles for pypy's cross compilation + """ import py +# XXX i think the below belongs somewhere under pypy/translator + class Platform(object): + def __init__(self, cc=None): + self.cc = None + def get_compiler(self): - return None + return self.cc def execute(self, cmd): return py.process.cmdexec(cmd) @@ -25,29 +31,20 @@ self.__dict__ == other.__dict__) class Maemo(Platform): - def get_compiler(self): - # XXX how to make this reliable??? - for x in ( - '/scratchbox/compilers/cs2007q3-glibc2.5-arm7/bin/arm-none-linux-gnueabi-gcc', - '/scratchbox/compilers/cs2005q3.2-glibc-arm/bin/sbox-arm-linux-gcc', - ): - if py.path.local(x).check(): - return x - raise ValueError("could not find scratchbox cross-compiler") - + def __init__(self, cc=None): + if cc is None: + for x in ( + '/scratchbox/compilers/cs2007q3-glibc2.5-arm7/bin/arm-none-linux-gnueabi-gcc', + '/scratchbox/compilers/cs2005q3.2-glibc-arm/bin/sbox-arm-linux-gcc', + ): + if py.path.local(x).check(): + cc = x + else: + raise ValueError("could not find scratchbox cross-compiler") + super(Platform, self).__init__(cc=cc) + def execute(self, cmd): return py.process.cmdexec('/scratchbox/login ' + cmd) -class OverloadCompilerPlatform(Platform): - def __init__(self, previous_platform, cc): - self.previous_platform = previous_platform - self.cc = cc - - def get_compiler(self): - return self.cc - - def execute(self, cmd): - return self.previous_platform.execute(cmd) - platform = Platform() Modified: pypy/dist/pypy/translator/tool/test/test_cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/test/test_cbuild.py (original) +++ pypy/dist/pypy/translator/tool/test/test_cbuild.py Sun Oct 5 09:14:09 2008 @@ -4,6 +4,7 @@ from pypy.translator.tool.cbuild import build_executable, \ ExternalCompilationInfo, compile_c_module from subprocess import Popen, PIPE, STDOUT +from pypy.rlib.pyplatform import Maemo def test_simple_executable(): print udir @@ -157,16 +158,6 @@ ExternalCompilationInfo.from_config_tool, 'dxowqbncpqympqhe-config') - def test_platforms(self): - from pypy.rlib.pyplatform import Maemo - eci = ExternalCompilationInfo(platform=Maemo()) - eci2 = ExternalCompilationInfo() - assert eci != eci2 - assert hash(eci) != hash(eci2) - assert repr(eci) != repr(eci2) - py.test.raises(Exception, eci2.merge, eci) - assert eci.merge(eci).platform == Maemo() - def test_platform(self): from pypy.rlib.pyplatform import Platform class Expected(Exception): @@ -200,11 +191,13 @@ assert Y(3) == Y(3) assert Y(2) != Y(3) - def test_standalone_maemo(self): - from pypy.rlib.pyplatform import Maemo - # XXX skip if there is no scratchbox + def checkscratchbox(self): if not py.path.local('/scratchbox/login').check(): py.test.skip("No scratchbox detected") + + def test_standalone_maemo(self): + self.checkscratchbox() + # XXX skip if there is no scratchbox tmpdir = self.tmpdir c_file = tmpdir.join('stand1.c') c_file.write(''' @@ -226,3 +219,14 @@ result = eci.platform.execute(output) assert result.startswith('4.0') + def test_platforms(self): + self.checkscratchbox() + eci = ExternalCompilationInfo(platform=Maemo()) + eci2 = ExternalCompilationInfo() + assert eci != eci2 + assert hash(eci) != hash(eci2) + assert repr(eci) != repr(eci2) + py.test.raises(Exception, eci2.merge, eci) + assert eci.merge(eci).platform == Maemo() + + From fijal at codespeak.net Sun Oct 5 10:57:36 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 5 Oct 2008 10:57:36 +0200 (CEST) Subject: [pypy-svn] r58601 - in pypy/dist/pypy: rlib translator/tool translator/tool/test Message-ID: <20081005085736.539F316A029@codespeak.net> Author: fijal Date: Sun Oct 5 10:57:32 2008 New Revision: 58601 Modified: pypy/dist/pypy/rlib/pyplatform.py pypy/dist/pypy/translator/tool/cbuild.py pypy/dist/pypy/translator/tool/test/test_cbuild.py Log: A test and a fix. Also fix existing tests. Modified: pypy/dist/pypy/rlib/pyplatform.py ============================================================================== --- pypy/dist/pypy/rlib/pyplatform.py (original) +++ pypy/dist/pypy/rlib/pyplatform.py Sun Oct 5 10:57:32 2008 @@ -10,7 +10,7 @@ class Platform(object): def __init__(self, cc=None): - self.cc = None + self.cc = cc def get_compiler(self): return self.cc @@ -30,6 +30,9 @@ return (self.__class__ is other.__class__ and self.__dict__ == other.__dict__) + def __repr__(self): + return '' % (self.__class__.__name__, self.cc) + class Maemo(Platform): def __init__(self, cc=None): if cc is None: @@ -39,9 +42,10 @@ ): if py.path.local(x).check(): cc = x + break else: raise ValueError("could not find scratchbox cross-compiler") - super(Platform, self).__init__(cc=cc) + Platform.__init__(self, cc=cc) def execute(self, cmd): return py.process.cmdexec('/scratchbox/login ' + cmd) Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Sun Oct 5 10:57:32 2008 @@ -176,7 +176,7 @@ for attr in self._ATTRIBUTES: val = getattr(self, attr) info.append("%s=%s" % (attr, repr(val))) - info.append("platform=%s" % self.platform.__class__.__name__) + info.append("platform=%s" % repr(self.platform)) return "" % ", ".join(info) def merge(self, *others): Modified: pypy/dist/pypy/translator/tool/test/test_cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/test/test_cbuild.py (original) +++ pypy/dist/pypy/translator/tool/test/test_cbuild.py Sun Oct 5 10:57:32 2008 @@ -228,5 +228,7 @@ assert repr(eci) != repr(eci2) py.test.raises(Exception, eci2.merge, eci) assert eci.merge(eci).platform == Maemo() - - + assert (ExternalCompilationInfo(platform=Maemo(cc='xxx')) != + ExternalCompilationInfo(platform=Maemo(cc='yyy'))) + assert (repr(ExternalCompilationInfo(platform=Maemo(cc='xxx'))) != + repr(ExternalCompilationInfo(platform=Maemo(cc='yyy')))) From witulski at codespeak.net Mon Oct 6 09:23:46 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Mon, 6 Oct 2008 09:23:46 +0200 (CEST) Subject: [pypy-svn] r58610 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081006072346.05F9316A143@codespeak.net> Author: witulski Date: Mon Oct 6 09:23:45 2008 New Revision: 58610 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py Log: Bug fixed. (ADD and SUB works correct) Reason : wrong intel doku Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Mon Oct 6 09:23:45 2008 @@ -168,8 +168,8 @@ # Opcode, mod, modrm1, modrm2, tttn(JUMPS), extraopcode # FIXME: rexB is set - _ADD_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, 0, "\x81", 3, None, 2) - _ADD_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x00", 3, None, None) + _ADD_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, 0, "\x81", 3, None, 0) + _ADD_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x01", 3, None, None) _AND_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x21", 3, None, None) @@ -218,7 +218,7 @@ _SHL_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xD3", 3, None, 4) _SHR_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xD3", 3, None, 5) - _SUB_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x28", 3, None, None) + _SUB_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x29", 3, None, None) _SUB_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, 0, "\x81", 3, None, 5) _XOR_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x31", 3, None, None) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py Mon Oct 6 09:23:45 2008 @@ -1,6 +1,7 @@ import os from pypy.rpython.lltypesystem import lltype, rffi from pypy.jit.codegen.x86_64.assembler import X86_64CodeBuilder +from pypy.jit.codegen.i386.codebuf import MachineCodeDumper #from ri386 import I386CodeBuilder #FIXME: name:i386 @@ -8,7 +9,7 @@ memhandler = __import__(modname, globals(), locals(), ['__doc__']) PTR = memhandler.PTR -print "ALBATROS " +machine_code_dumper = MachineCodeDumper() class CodeBlockOverflow(Exception): pass @@ -21,6 +22,7 @@ self._size = map_size self._pos = 0 self._all = [] + self._last_dump_start = 0 #FIXME: def write(self, data): p = self._pos @@ -36,6 +38,9 @@ baseaddr = rffi.cast(lltype.Signed, self._data) return baseaddr + self._pos - - - + def done(self): + # normally, no special action is needed here + if machine_code_dumper.enabled: + machine_code_dumper.dump_range(self, self._last_dump_start, + self._pos) + self._last_dump_start = self._pos Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Mon Oct 6 09:23:45 2008 @@ -150,12 +150,11 @@ #FIXME: can only jump 32bit - #FIXME: -6 displacement: the displ+ rip of next instr def jump_if_true(self, gv_condition, args_for_jump_gv): targetbuilder = Builder() self.mc.CMP(gv_condition, Immediate32(0)) displ = self.calc_32bit_displacement(self.mc.tell(),targetbuilder.mc.tell()) - self.mc.JNE(displ-6) + self.mc.JNE(displ) #targetbuilder.come_from(self.mc, 'JNE') return targetbuilder @@ -244,7 +243,7 @@ return L def _close(self): - pass + self.mc.done() def calc_32bit_displacement(self, curr_addr, want_jump_to): return want_jump_to-curr_addr Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py Mon Oct 6 09:23:45 2008 @@ -14,9 +14,9 @@ def test_add(): mc = AsmTest() mc.ADD(Register64("rax"), Register64("r11")) - assert mc.get_as_string() == "\x4C\x00\xD8" + assert mc.get_as_string() == "\x4C\x01\xD8" mc.ADD(Register64("rbx"), Register64("rbx")) - assert mc.get_as_string() == "\x4C\x00\xD8\x48\x00\xDB" + assert mc.get_as_string() == "\x4C\x01\xD8\x48\x01\xDB" def test_mov(): mc = AsmTest() From cami at codespeak.net Mon Oct 6 10:32:16 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Mon, 6 Oct 2008 10:32:16 +0200 (CEST) Subject: [pypy-svn] r58611 - pypy/dist/pypy/lang/gameboy/debug Message-ID: <20081006083216.D264116A113@codespeak.net> Author: cami Date: Mon Oct 6 10:32:15 2008 New Revision: 58611 Modified: pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py Log: updated remote debugger to the newer object model of video Modified: pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py Mon Oct 6 10:32:15 2008 @@ -74,6 +74,7 @@ # RPC =================================================================== def close(self): + pdb.set_trace() if not self.is_closed: print "python: called close" self.server_close() @@ -146,7 +147,7 @@ @printframe("comparing registers") def compare_registers(self, registers): - for reg in [("a", self.cpu.a.get()), ("f", self.cpu.f.get()), + for reg in [("a", self.cpu.a.get()), ("f", self.cpu.flag.get()), ("b", self.cpu.b.get()), ("c", self.cpu.c.get()), ("d", self.cpu.d.get()), ("e", self.cpu.e.get()), ("h", self.cpu.h.get()), ("l", self.cpu.l.get()), @@ -227,21 +228,21 @@ self.gameboy_debug.video.object_palette_1, \ video["obp1"]) self.print_check("video scx", \ - self.gameboy_debug.video.scroll_x, video["scx"]) + self.gameboy_debug.video.background.scroll_x, video["scx"]) self.print_check("video scy", \ - self.gameboy_debug.video.scroll_y, video["scy"]) + self.gameboy_debug.video.background.scroll_y, video["scy"]) self.print_check("video stat", \ self.gameboy_debug.video.status.read(), video["stat"]) self.print_check("video transfer", \ self.gameboy_debug.video.transfer, video["transfer"]) self.print_check("video vblank", \ - self.gameboy_debug.video.vblank, video["vblank"]) + self.gameboy_debug.video.v_blank, video["vblank"]) self.print_check("video wly", \ - self.gameboy_debug.video.window_line_y, video["wly"]) + self.gameboy_debug.video.window.line_y, video["wly"]) self.print_check("video wx", \ - self.gameboy_debug.video.window_x, video["wx"]) + self.gameboy_debug.video.window.x, video["wx"]) self.print_check("video wy", \ - self.gameboy_debug.video.window_y, video["wy"]) + self.gameboy_debug.video.window.y, video["wy"]) @printframe("comparing timer") def compare_timer(self, data): @@ -327,8 +328,6 @@ return #self.prompt_for_user_input() - - def prompt_for_user_input(self): if self.showed_skip_message_count < 2: print ">> enter skip, default is 0:" Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Mon Oct 6 10:32:15 2008 @@ -44,7 +44,7 @@ except: print "stopped" - +# ------------------------------------------------------------------------------ JMARIO_DIR = str(py.magic.autopath().dirpath().dirpath()\ .dirpath().dirpath()\ Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py Mon Oct 6 10:32:15 2008 @@ -6,6 +6,7 @@ from pypy.lang.gameboy.debug import debug from pypy.lang.gameboy.debug.debug_socket_memory import * import time +import pdb # GAMEBOY ---------------------------------------------------------------------- @@ -26,8 +27,10 @@ self.sound_driver = SoundDriverImplementation() - def handle_execution_error(self): + def handle_execution_error(self, error): + print error print "closing socket connections" + pdb.set_trace() self.is_running = False debug.print_results() self.memory.close() @@ -54,6 +57,7 @@ def update_display(self): # dont update the display, we're here only for testing pass + # JOYPAD DRIVER ---------------------------------------------------------------- @@ -62,6 +66,9 @@ def __init__(self): JoypadDriver.__init__(self) + + def update(self, event): + pass; # SOUND DRIVER ----------------------------------------------------------------- From cami at codespeak.net Mon Oct 6 10:34:59 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Mon, 6 Oct 2008 10:34:59 +0200 (CEST) Subject: [pypy-svn] r58612 - pypy/dist/pypy/lang/gameboy/debug Message-ID: <20081006083459.43E9016A14B@codespeak.net> Author: cami Date: Mon Oct 6 10:34:58 2008 New Revision: 58612 Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Log: made platform check for importing the NSApplication package in the debug entry point Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Mon Oct 6 10:34:58 2008 @@ -8,8 +8,9 @@ # ------------------------------------------------------------------------------ -from AppKit import NSApplication -NSApplication.sharedApplication() +if sys.platform == 'darwin': + from AppKit import NSApplication + NSApplication.sharedApplication() # ------------------------------------------------------------------------------ ROM_PATH = str(py.magic.autopath().dirpath().dirpath())+"/rom" From cami at codespeak.net Mon Oct 6 10:36:17 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Mon, 6 Oct 2008 10:36:17 +0200 (CEST) Subject: [pypy-svn] r58613 - pypy/dist/pypy/lang/gameboy/debug Message-ID: <20081006083617.B92A716A151@codespeak.net> Author: cami Date: Mon Oct 6 10:36:17 2008 New Revision: 58613 Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Log: fixed wrong indent :/ Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Mon Oct 6 10:36:17 2008 @@ -10,7 +10,8 @@ if sys.platform == 'darwin': from AppKit import NSApplication - NSApplication.sharedApplication() + NSApplication.sharedApplication() + # ------------------------------------------------------------------------------ ROM_PATH = str(py.magic.autopath().dirpath().dirpath())+"/rom" From cfbolz at codespeak.net Mon Oct 6 10:46:33 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 10:46:33 +0200 (CEST) Subject: [pypy-svn] r58616 - pypy/extradoc/sprintinfo/october-2008 Message-ID: <20081006084633.F0DF616A0B7@codespeak.net> Author: cfbolz Date: Mon Oct 6 10:46:33 2008 New Revision: 58616 Added: pypy/extradoc/sprintinfo/october-2008/planning.txt (contents, props changed) Log: (all): planning for today Added: pypy/extradoc/sprintinfo/october-2008/planning.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/october-2008/planning.txt Mon Oct 6 10:46:33 2008 @@ -0,0 +1,51 @@ + +D?sseldorf Sprint Planning +========================== + +People present: + - Carl Friedrich + - John + - Anto + - Alexander + - Samuele + - Iko + - Armin + - Holger in theory + + +Tasks: + + - improve the 64-bit JIT backend (John, Anto) + + + - merge the pypy-pytrunk branch (Samuele) + + - run the CPython tests through buildbot on pypy-c + + - look at the TODO list of the buildbot stuff + + - merge the 2.5 branch + + - windows buildbot slave + + + + + - looking at the static data of pypy-c (Carl Friedrich, Alexander) + + - use shared dicts for oldstyle classes (Carl Friedrich, Alexander) + + - malloc-removal-directed inlining to reduce the code size (Armin, Iko) + + - measuring memory behaviour + + - run memory-benchmarks nightly? + + + - builtin-profiling branch needs to be merged + +Discussion Tasks: + + - JIT roadmap + - C++ bindings? + - release plans, goals From arigo at codespeak.net Mon Oct 6 10:54:44 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 10:54:44 +0200 (CEST) Subject: [pypy-svn] r58617 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081006085444.AADA3169E23@codespeak.net> Author: arigo Date: Mon Oct 6 10:54:43 2008 New Revision: 58617 Added: pypy/dist/pypy/translator/backendopt/mallocv.py (contents, props changed) pypy/dist/pypy/translator/backendopt/test/test_mallocv.py - copied, changed from r58615, pypy/dist/pypy/translator/backendopt/test/test_malloc.py Log: In-progress. Another approach to malloc removal which is abstract-interpretation-based. Added: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Mon Oct 6 10:54:43 2008 @@ -0,0 +1,236 @@ +from pypy.objspace.flow.model import Variable, Constant, Block, Link +from pypy.objspace.flow.model import SpaceOperation +from pypy.translator.backendopt.support import log + + +# ____________________________________________________________ + + +class CannotVirtualize(Exception): + pass + + +class MallocVirtualizer(object): + + def __init__(self, graphs): + self.graphs = list(graphs) + self.cache = BlockSpecCache() + self.count_virtualized = 0 + + def report_result(self): + log.mallocv('removed %d mallocs so far' % (self.count_virtualized,)) + return self.count_virtualized + + def find_all_mallocs(self, graph): + result = [] + for block in graph.iterblocks(): + for op in block.operations: + if op.opname == 'malloc': + result.append((block, op)) + return result + + def remove_mallocs_once(self, verbose=False): + prev = self.count_virtualized + for graph in self.graphs: + all_mallocs = self.find_all_mallocs(graph) + for block, op in all_mallocs: + try: + self.try_remove_malloc(block, op) + if verbose: + log.mallocv('%s removed' % (op.result,)) + break # don't continue on this graph, which was mutated + except CannotVirtualize, e: + if verbose: + log.mallocv('%s failed: %s' % (op.result, e)) + progress = self.report_result() - prev + return progress + + def try_remove_malloc(self, block, op): + mallocspec = MallocSpecializer(self, op.result.concretetype.TO) + mallocspec.remove_malloc(block, op.result) + mallocspec.propagate_specializations() + # if we read this point without a CannotVirtualize, success + mallocspec.commit() + self.count_virtualized += 1 + + +class BlockSpecCache(object): + + def __init__(self, fallback=None): + self.specialized_blocks = {} + self.block_keys = {} + self.fallback = fallback + + def lookup_spec_block(self, block, extra_key): + key = self.block_keys.get(block, frozenset()) + key = key.union([extra_key]) + try: + return self.specialized_blocks[key] + except KeyError: + if self.fallback is None: + return None + else: + return self.fallback.specialized_blocks.get(key) + + def remember_spec_block(self, block, extra_key, specblock): + key = self.block_keys.get(block, frozenset()) + key = key.union([extra_key]) + self.specialized_blocks[key] = specblock + self.block_keys[specblock] = key + + def push_changes(self): + self.fallback.specialized_blocks.update(self.specialized_blocks) + self.fallback.block_keys.update(self.block_keys) + + +class MallocSpecializer(object): + + def __init__(self, mallocv, MALLOCTYPE): + self.mallocv = mallocv + self.MALLOCTYPE = MALLOCTYPE + self.names_and_types = [] + self.name2index = {} + self.initialize_type(MALLOCTYPE) + self.pending_specializations = [] + self.cache = BlockSpecCache(fallback=mallocv.cache) + + def initialize_type(self, TYPE): + fieldnames = TYPE._names + firstname, FIRSTTYPE = TYPE._first_struct() + if FIRSTTYPE is not None: + self.initialize_type(FIRSTTYPE) + fieldnames = fieldnames[1:] + for name in fieldnames: + FIELDTYPE = TYPE._flds[name] + self.name2index[name] = len(self.names_and_types) + self.names_and_types.append((name, FIELDTYPE)) + + def remove_malloc(self, block, v_result): + self.startblock = block + spec = BlockSpecializer(self, v_result) + spec.initialize_renamings(block.inputargs) + self.newinputargs = spec.expand_vars(block.inputargs) + self.newoperations = spec.specialize_operations(block.operations) + self.newexits = self.follow_exits(block, spec) + + def follow_exits(self, block, spec): + newlinks = [] + for link in block.exits: + targetblock = link.target + for v1, v2 in zip(link.args, link.target.inputargs): + if v1 in spec.curvars: + targetblock = self.get_specialized_block(targetblock, v2) + newlink = Link(spec.expand_vars(link.args), targetblock) + newlinks.append(newlink) + return newlinks + + def get_specialized_block(self, block, v): + specblock = self.cache.lookup_spec_block(block, (self.MALLOCTYPE, v)) + if specblock is None: + if block.operations == (): + raise CannotVirtualize("return or except block") + spec = BlockSpecializer(self, v) + spec.make_expanded_vars() + spec.initialize_renamings(block.inputargs) + specblock = Block(spec.expand_vars(block.inputargs)) + self.pending_specializations.append((spec, block, specblock)) + self.cache.remember_spec_block(block, (self.MALLOCTYPE, v), + specblock) + return specblock + + def propagate_specializations(self): + while self.pending_specializations: + spec, block, specblock = self.pending_specializations.pop() + specblock.operations = spec.specialize_operations(block.operations) + specblock.closeblock(*self.follow_exits(block, spec)) + + def commit(self): + self.startblock.inputargs = self.newinputargs + self.startblock.operations = self.newoperations + self.startblock.recloseblock(*self.newexits) + self.cache.push_changes() + + +class BlockSpecializer(object): + + def __init__(self, mallocspec, v): + self.mallocspec = mallocspec + self.curvars = set([v]) + + def make_expanded_vars(self): + self.expanded_v = [] + for name, FIELDTYPE in self.mallocspec.names_and_types: + v = Variable(name) + v.concretetype = FIELDTYPE + self.expanded_v.append(v) + + def make_expanded_zero_constants(self): + self.expanded_v = [] + for name, FIELDTYPE in self.mallocspec.names_and_types: + c = Constant(FIELDTYPE._defl()) + c.concretetype = FIELDTYPE + self.expanded_v.append(c) + + def rename_nonvirtual(self, v, where=None): + if v in self.curvars: + raise CannotVirtualize(where) + [v2] = self.renamings[v] + return v2 + + def expand_vars(self, vars): + result_v = [] + for v in vars: + result_v += self.renamings[v] + return result_v + + def initialize_renamings(self, inputargs): + self.renamings = {} + for v in inputargs: + if v in self.curvars: + self.renamings[v] = self.expanded_v + else: + v2 = Variable(v) + v2.concretetype = v.concretetype + self.renamings[v] = [v2] + + def specialize_operations(self, operations): + newoperations = [] + for op in operations: + meth = getattr(self, 'handle_op_' + op.opname, + self.handle_default) + newoperations += meth(op) + return newoperations + + def handle_default(self, op): + newargs = [self.rename_nonvirtual(v, op) for v in op.args] + newresult = Variable(op.result) + newresult.concretetype = op.result.concretetype + self.renamings[op.result] = [newresult] + return [SpaceOperation(op.opname, newargs, newresult)] + + def handle_op_getfield(self, op): + if op.args[0] in self.curvars: + fieldname = op.args[1].value + index = self.mallocspec.name2index[fieldname] + v_field = self.expanded_v[index] + self.renamings[op.result] = [v_field] + return [] + else: + return self.handle_default(op) + + def handle_op_setfield(self, op): + if op.args[0] in self.curvars: + fieldname = op.args[1].value + index = self.mallocspec.name2index[fieldname] + self.expanded_v[index] = self.rename_nonvirtual(op.args[2], op) + return [] + else: + return self.handle_default(op) + + def handle_op_malloc(self, op): + if op.result in self.curvars: + self.make_expanded_zero_constants() + self.renamings[op.result] = self.expanded_v + return [] + else: + return self.handle_default(op) Copied: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (from r58615, pypy/dist/pypy/translator/backendopt/test/test_malloc.py) ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Mon Oct 6 10:54:43 2008 @@ -1,10 +1,11 @@ import py -from pypy.translator.backendopt.malloc import LLTypeMallocRemover, OOTypeMallocRemover +from pypy.translator.backendopt.mallocv import MallocVirtualizer from pypy.translator.backendopt.inline import inline_function from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.translator import TranslationContext, graphof from pypy.translator import simplify from pypy.objspace.flow.model import checkgraph, flatten, Block, mkentrymap +from pypy.objspace.flow.model import summary from pypy.rpython.llinterp import LLInterpreter from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype @@ -20,16 +21,16 @@ py.test.skip(msg) def check_malloc_removed(cls, graph): - remover = cls.MallocRemover() + #remover = cls.MallocRemover() checkgraph(graph) count1 = count2 = 0 for node in flatten(graph): if isinstance(node, Block): for op in node.operations: - if op.opname == cls.MallocRemover.MALLOC_OP: + if op.opname == 'malloc': #cls.MallocRemover.MALLOC_OP: S = op.args[0].value - if not remover.union_wrapper(S): # union wrappers are fine - count1 += 1 + #if not remover.union_wrapper(S): # union wrappers are fine + count1 += 1 if op.opname in ('direct_call', 'indirect_call'): count2 += 1 assert count1 == 0 # number of mallocs left @@ -37,7 +38,6 @@ check_malloc_removed = classmethod(check_malloc_removed) def check(self, fn, signature, args, expected_result, must_be_removed=True): - remover = self.MallocRemover() t = TranslationContext() t.buildannotator().build_types(fn, signature) t.buildrtyper(type_system=self.type_system).specialize() @@ -46,9 +46,11 @@ t.view() # to detect missing keepalives and broken intermediate graphs, # we do the loop ourselves instead of calling remove_simple_mallocs() + maxiter = 100 + mallocv = MallocVirtualizer(t.graphs) while True: - progress = remover.remove_mallocs_once(graph) - simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks())) + progress = mallocv.remove_mallocs_once(verbose=True) + #simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks())) if progress and option.view: t.view() if expected_result is not Ellipsis: @@ -69,9 +71,12 @@ t = x-y, x+y s, d = t return s*d - self.check(fn1, [int, int], [15, 10], 125) + graph = self.check(fn1, [int, int], [15, 10], 125) + insns = summary(graph) + assert insns['int_mul'] == 1 def test_fn2(self): + py.test.skip("redo me") class T: pass def fn2(x, y): @@ -85,12 +90,14 @@ self.check(fn2, [int, int], [-6, 7], -13) def test_fn3(self): + py.test.skip("redo me") def fn3(x): a, ((b, c), d, e) = x+1, ((x+2, x+3), x+4, x+5) return a+b+c+d+e self.check(fn3, [int], [10], 65) def test_fn4(self): + py.test.skip("redo me") class A: pass class B(A): @@ -104,6 +111,7 @@ self.check(fn4, [int], [42], 42) def test_fn5(self): + py.test.skip("redo me") class A: attr = 666 class B(A): @@ -114,6 +122,7 @@ self.check(fn5, [], [], 42) def test_aliasing(self): + py.test.skip("redo me") class A: pass def fn6(n): @@ -133,9 +142,10 @@ class TestLLTypeMallocRemoval(BaseMallocRemovalTest): type_system = 'lltype' - MallocRemover = LLTypeMallocRemover + #MallocRemover = LLTypeMallocRemover def test_with_keepalive(self): + py.test.skip("redo me") from pypy.rlib.objectmodel import keepalive_until_here def fn1(x, y): if x > 0: @@ -148,6 +158,7 @@ self.check(fn1, [int, int], [15, 10], 125) def test_dont_remove_with__del__(self): + py.test.skip("redo me") import os delcalls = [0] class A(object): @@ -177,6 +188,7 @@ assert op.opname == "malloc" def test_add_keepalives(self): + py.test.skip("redo me") class A: pass SMALL = lltype.Struct('SMALL', ('x', lltype.Signed)) @@ -194,6 +206,7 @@ self.check(fn7, [int], [10], 55, must_be_removed=False) def test_getsubstruct(self): + py.test.skip("redo me") py.test.skip("fails because of the interior structure changes") SMALL = lltype.Struct('SMALL', ('x', lltype.Signed)) BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL)) @@ -207,6 +220,7 @@ self.check(fn, [int, int], [100, 58], 42) def test_fixedsizearray(self): + py.test.skip("redo me") py.test.skip("fails because of the interior structure changes") A = lltype.FixedSizeArray(lltype.Signed, 3) S = lltype.GcStruct('S', ('a', A)) @@ -221,6 +235,7 @@ self.check(fn, [int, int], [100, 42], 58) def test_wrapper_cannot_be_removed(self): + py.test.skip("redo me") SMALL = lltype.OpaqueType('SMALL') BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL)) @@ -233,6 +248,7 @@ self.check(fn, [], [], None, must_be_removed=False) def test_direct_fieldptr(self): + py.test.skip("redo me") S = lltype.GcStruct('S', ('x', lltype.Signed)) def fn(): @@ -244,6 +260,7 @@ self.check(fn, [], [], 11) def test_direct_fieldptr_2(self): + py.test.skip("redo me") T = lltype.GcStruct('T', ('z', lltype.Signed)) S = lltype.GcStruct('S', ('t', T), ('x', lltype.Signed), @@ -261,6 +278,7 @@ self.check(fn, [], [], 42) def test_getarraysubstruct(self): + py.test.skip("redo me") py.test.skip("fails because of the interior structure changes") U = lltype.Struct('U', ('n', lltype.Signed)) for length in [1, 2]: @@ -274,6 +292,7 @@ self.check(fn, [], [], 12) def test_ptr_nonzero(self): + py.test.skip("redo me") S = lltype.GcStruct('S') def fn(): s = lltype.malloc(S) @@ -281,6 +300,7 @@ self.check(fn, [], [], True) def test_substruct_not_accessed(self): + py.test.skip("redo me") SMALL = lltype.Struct('SMALL', ('x', lltype.Signed)) BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL)) def fn(): @@ -291,6 +311,7 @@ self.check(fn, [], [], 12) def test_union(self): + py.test.skip("redo me") py.test.skip("fails because of the interior structure changes") UNION = lltype.Struct('UNION', ('a', lltype.Signed), ('b', lltype.Signed), hints = {'union': True}) @@ -303,6 +324,7 @@ self.check(fn, [], [], Ellipsis) def test_keep_all_keepalives(self): + py.test.skip("redo me") SIZE = llmemory.sizeof(lltype.Signed) PARRAY = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1)) class A: @@ -335,6 +357,7 @@ assert link.prevblock.operations[-1].opname == 'keepalive' def test_nested_struct(self): + py.test.skip("redo me") S = lltype.GcStruct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('s', S)) def f(x): @@ -346,6 +369,7 @@ graph = self.check(f, [int], [42], 2 * 42) def test_interior_ptr(self): + py.test.skip("redo me") py.test.skip("fails") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('s', S)) @@ -356,6 +380,7 @@ graph = self.check(f, [int], [42], 42) def test_interior_ptr_with_index(self): + py.test.skip("redo me") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcArray(S) def f(x): @@ -365,6 +390,7 @@ graph = self.check(f, [int], [42], 42) def test_interior_ptr_with_field_and_index(self): + py.test.skip("redo me") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(x): @@ -374,6 +400,7 @@ graph = self.check(f, [int], [42], 42) def test_interior_ptr_with_index_and_field(self): + py.test.skip("redo me") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.Struct("T", ('s', S)) U = lltype.GcArray(T) @@ -384,9 +411,9 @@ graph = self.check(f, [int], [42], 42) -class TestOOTypeMallocRemoval(BaseMallocRemovalTest): +class DISABLED_TestOOTypeMallocRemoval(BaseMallocRemovalTest): type_system = 'ootype' - MallocRemover = OOTypeMallocRemover + #MallocRemover = OOTypeMallocRemover def test_oononnull(self): FOO = ootype.Instance('Foo', ootype.ROOT) From xoraxax at codespeak.net Mon Oct 6 11:22:01 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 6 Oct 2008 11:22:01 +0200 (CEST) Subject: [pypy-svn] r58618 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20081006092201.D703216A1CC@codespeak.net> Author: xoraxax Date: Mon Oct 6 11:22:00 2008 New Revision: 58618 Modified: pypy/dist/pypy/module/__builtin__/interp_classobj.py pypy/dist/pypy/module/__builtin__/test/test_classobj.py Log: (cfbolz, xoraxax) Use sharing dicts for oldstyle class instance dicts. Modified: pypy/dist/pypy/module/__builtin__/interp_classobj.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/interp_classobj.py (original) +++ pypy/dist/pypy/module/__builtin__/interp_classobj.py Mon Oct 6 11:22:00 2008 @@ -289,7 +289,7 @@ space.w_TypeError, space.wrap("instance() first arg must be class")) if space.is_w(w_dict, space.w_None): - w_dict = space.newdict() + w_dict = None elif not space.is_true(space.isinstance(w_dict, space.w_dict)): raise OperationError( space.w_TypeError, @@ -299,7 +299,12 @@ class W_InstanceObject(Wrappable): def __init__(self, space, w_class, w_dict=None): if w_dict is None: - w_dict = space.newdict() + if space.config.objspace.std.withsharingdict: + from pypy.objspace.std import dictmultiobject + w_dict = dictmultiobject.W_DictMultiObject(space, + sharing=True) + else: + w_dict = space.newdict() assert isinstance(w_class, W_ClassObject) self.w_class = w_class self.w_dict = w_dict Modified: pypy/dist/pypy/module/__builtin__/test/test_classobj.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_classobj.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_classobj.py Mon Oct 6 11:22:00 2008 @@ -1,3 +1,6 @@ +from pypy.conftest import gettestobjspace +from pypy.interpreter import gateway + class AppTestOldstyle(object): @@ -755,3 +758,22 @@ Z().__del__ = lambda self: None finally: warnings.simplefilter('default', RuntimeWarning) + +class AppTestOldStyleSharing(AppTestOldstyle): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withsharingdict": True}) + def is_sharing(space, w_inst): + from pypy.objspace.std.dictmultiobject import SharedDictImplementation, W_DictMultiObject + w_d = w_inst.getdict() + return space.wrap(isinstance(w_d, W_DictMultiObject) and + isinstance(w_d.implementation, SharedDictImplementation)) + cls.w_is_sharing = cls.space.wrap(gateway.interp2app(is_sharing)) + + + def test_real_sharing(self): + class A: + def __init__(self): + self.x = 42 + A1, A2, A3 = A(), A(), A() + assert self.is_sharing(A3) + assert self.is_sharing(A2) From arigo at codespeak.net Mon Oct 6 11:52:45 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 11:52:45 +0200 (CEST) Subject: [pypy-svn] r58621 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081006095245.A8DC316A1A2@codespeak.net> Author: arigo Date: Mon Oct 6 11:52:43 2008 New Revision: 58621 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: (iko, arigo) Support virtualizing objects that go into calls, by specializing the called functions. (In-progress; this is wrong so far for mutable objects.) Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Mon Oct 6 11:52:43 2008 @@ -1,6 +1,8 @@ from pypy.objspace.flow.model import Variable, Constant, Block, Link -from pypy.objspace.flow.model import SpaceOperation +from pypy.objspace.flow.model import SpaceOperation, FunctionGraph from pypy.translator.backendopt.support import log +from pypy.rpython.typesystem import getfunctionptr +from pypy.rpython.lltypesystem import lltype # ____________________________________________________________ @@ -13,7 +15,8 @@ class MallocVirtualizer(object): def __init__(self, graphs): - self.graphs = list(graphs) + self.graphs = graphs + self.new_graphs = {} self.cache = BlockSpecCache() self.count_virtualized = 0 @@ -42,6 +45,7 @@ except CannotVirtualize, e: if verbose: log.mallocv('%s failed: %s' % (op.result, e)) + self.put_new_graphs_back_in_translator() progress = self.report_result() - prev return progress @@ -53,12 +57,19 @@ mallocspec.commit() self.count_virtualized += 1 + def put_new_graphs_back_in_translator(self): + for graph in self.cache.graph_starting_at.values(): + if graph not in self.new_graphs: + self.new_graphs[graph] = True + self.graphs.append(graph) + class BlockSpecCache(object): def __init__(self, fallback=None): self.specialized_blocks = {} self.block_keys = {} + self.graph_starting_at = {} self.fallback = fallback def lookup_spec_block(self, block, extra_key): @@ -78,9 +89,22 @@ self.specialized_blocks[key] = specblock self.block_keys[specblock] = key + def lookup_graph_starting_at(self, startblock): + try: + return self.graph_starting_at[startblock] + except KeyError: + if self.fallback is None: + return None + else: + return self.fallback.graph_starting_at.get(startblock) + + def remember_graph_starting_at(self, startblock, graph): + self.graph_starting_at[startblock] = graph + def push_changes(self): self.fallback.specialized_blocks.update(self.specialized_blocks) self.fallback.block_keys.update(self.block_keys) + self.fallback.graph_starting_at.update(self.graph_starting_at) class MallocSpecializer(object): @@ -138,6 +162,15 @@ specblock) return specblock + def get_specialized_graph(self, graph, v): + block = graph.startblock + specblock = self.get_specialized_block(block, v) + specgraph = self.cache.lookup_graph_starting_at(specblock) + if specgraph is None: + specgraph = FunctionGraph(graph.name + '_spec', specblock) + self.cache.remember_graph_starting_at(specblock, specgraph) + return specgraph + def propagate_specializations(self): while self.pending_specializations: spec, block, specblock = self.pending_specializations.pop() @@ -172,6 +205,8 @@ self.expanded_v.append(c) def rename_nonvirtual(self, v, where=None): + if isinstance(v, Constant): + return v if v in self.curvars: raise CannotVirtualize(where) [v2] = self.renamings[v] @@ -234,3 +269,34 @@ return [] else: return self.handle_default(op) + + def handle_op_direct_call(self, op): + fobj = op.args[0].value._obj + if hasattr(fobj, 'graph'): + graph = fobj.graph + nb_args = len(op.args) - 1 + assert nb_args == len(graph.getargs()) + newargs = [] + for i in range(nb_args): + v1 = op.args[1+i] + if v1 not in self.curvars: + newargs.append(v1) + else: + inputarg_index_in_specgraph = len(newargs) + v2 = graph.getargs()[inputarg_index_in_specgraph] + assert v1.concretetype == v2.concretetype + specgraph = self.mallocspec.get_specialized_graph(graph, + v2) + newargs.extend(self.expanded_v) + graph = specgraph + assert len(newargs) == len(graph.getargs()) + fspecptr = getfunctionptr(graph) + newargs.insert(0, Constant(fspecptr, + concretetype=lltype.typeOf(fspecptr))) + newresult = Variable(op.result) + newresult.concretetype = op.result.concretetype + self.renamings[op.result] = [newresult] + newop = SpaceOperation('direct_call', newargs, newresult) + return [newop] + else: + return self.handle_default(op) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Mon Oct 6 11:52:43 2008 @@ -23,18 +23,15 @@ def check_malloc_removed(cls, graph): #remover = cls.MallocRemover() checkgraph(graph) - count1 = count2 = 0 + count = 0 for node in flatten(graph): if isinstance(node, Block): for op in node.operations: if op.opname == 'malloc': #cls.MallocRemover.MALLOC_OP: S = op.args[0].value #if not remover.union_wrapper(S): # union wrappers are fine - count1 += 1 - if op.opname in ('direct_call', 'indirect_call'): - count2 += 1 - assert count1 == 0 # number of mallocs left - assert count2 == 0 # number of calls left + count += 1 + assert count == 0 # number of mallocs left check_malloc_removed = classmethod(check_malloc_removed) def check(self, fn, signature, args, expected_result, must_be_removed=True): @@ -75,6 +72,14 @@ insns = summary(graph) assert insns['int_mul'] == 1 + def test_direct_call(self): + def g(t): + a, b = t + return a * b + def f(x): + return g((x+1, x-1)) + graph = self.check(f, [int], [10], 99) + def test_fn2(self): py.test.skip("redo me") class T: From cfbolz at codespeak.net Mon Oct 6 11:54:31 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 11:54:31 +0200 (CEST) Subject: [pypy-svn] r58622 - pypy/branch/2.5-features/pypy/objspace/flow/test Message-ID: <20081006095431.8BF2916A1A2@codespeak.net> Author: cfbolz Date: Mon Oct 6 11:54:31 2008 New Revision: 58622 Removed: pypy/branch/2.5-features/pypy/objspace/flow/test/test___import__.py Log: kill pointless test From pedronis at codespeak.net Mon Oct 6 12:14:10 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 6 Oct 2008 12:14:10 +0200 (CEST) Subject: [pypy-svn] r58623 - in pypy/dist: . pypy pypy/doc pypy/interpreter/test pypy/tool pypy/tool/pytest pypy/tool/test Message-ID: <20081006101410.1CBCE16A053@codespeak.net> Author: pedronis Date: Mon Oct 6 12:14:08 2008 New Revision: 58623 Added: pypy/dist/pypy/testrunner_cfg.py - copied unchanged from r58619, pypy/branch/pypy-pytrunk/pypy/testrunner_cfg.py Modified: pypy/dist/ (props changed) pypy/dist/pypy/conftest.py pypy/dist/pypy/doc/configuration.txt pypy/dist/pypy/doc/conftest.py pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/interpreter/test/test_appinterp.py pypy/dist/pypy/interpreter/test/test_code.py pypy/dist/pypy/tool/ansi_mandelbrot.py pypy/dist/pypy/tool/ansi_print.py pypy/dist/pypy/tool/pytest/appsupport.py pypy/dist/pypy/tool/pytest/pypy_test_failure_demo.py pypy/dist/pypy/tool/test/test_conftest1.py pypy/dist/pypy/tool/test/test_pytestsupport.py Log: (hpk, pedronis) merging pypy-pytrunk branch pypy dist/py now points to py/trunk/py Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Mon Oct 6 12:14:08 2008 @@ -29,9 +29,10 @@ help="run applevel tests directly on python interpreter (not through PyPy)"), Option('--direct', action="store_true", default=False, dest="rundirect", - help="run pexpect tests directly") + help="run pexpect tests directly"), ) + _SPACECACHE={} def gettestobjspace(name=None, **kwds): """ helper for instantiating and caching space's for testing. @@ -267,6 +268,11 @@ return space +class AppError(Exception): + + def __init__(self, excinfo): + self.excinfo = excinfo + class PyPyTestFunction(py.test.collect.Function): # All PyPy test items catch and display OperationErrors specially. # @@ -274,13 +280,18 @@ try: target(*args) except OperationError, e: + tb = sys.exc_info()[2] if e.match(space, space.w_KeyboardInterrupt): - tb = sys.exc_info()[2] raise OpErrKeyboardInterrupt, OpErrKeyboardInterrupt(), tb appexcinfo = appsupport.AppExceptionInfo(space, e) if appexcinfo.traceback: - raise Failed(excinfo=appsupport.AppExceptionInfo(space, e)) - raise + raise AppError, AppError(appexcinfo), tb + raise + + def repr_failure(self, excinfo, outerr): + if excinfo.errisinstance(AppError): + excinfo = excinfo.value.excinfo + return super(PyPyTestFunction, self).repr_failure(excinfo, outerr) _pygame_imported = False Modified: pypy/dist/pypy/doc/configuration.txt ============================================================================== --- pypy/dist/pypy/doc/configuration.txt (original) +++ pypy/dist/pypy/doc/configuration.txt Mon Oct 6 12:14:08 2008 @@ -132,6 +132,7 @@ ``OptionDescription`` instance. The attributes of the ``Config`` objects are the names of the children of the ``OptionDescription``. Example:: + >>> from pypy.config.config import OptionDescription, Config, BoolOption >>> descr = OptionDescription("options", "", [ ... BoolOption("bool", "", default=False)]) >>> Modified: pypy/dist/pypy/doc/conftest.py ============================================================================== --- pypy/dist/pypy/doc/conftest.py (original) +++ pypy/dist/pypy/doc/conftest.py Mon Oct 6 12:14:08 2008 @@ -1,6 +1,5 @@ import py -from py.__.doc.conftest import Directory, DoctestText, ReSTChecker -from py.__.rest.directive import register_linkrole +from py.__.doc.conftest import Directory, DoctestText, DocfileTests thisdir = py.magic.autopath().dirpath() @@ -15,43 +14,34 @@ ) class PyPyDoctestText(DoctestText): - - def run(self): + def runtest(self): if not option.doctests: py.test.skip("specify --enable-doctests to run doctests") - # XXX refine doctest support with respect to scoping - return super(PyPyDoctestText, self).run() - - def execute(self, module, docstring): + super(PyPyDoctestText, self).runtest() + + def getcontent(self): # XXX execute PyPy prompts as well + # but for now just get rid of those lines l = [] - for line in docstring.split('\n'): + for line in super(PyPyDoctestText, self).getcontent().split('\n'): if line.find('>>>>') != -1: line = "" l.append(line) - text = "\n".join(l) - super(PyPyDoctestText, self).execute(module, text) - - #mod = py.std.types.ModuleType(self.fspath.basename, text) - #self.mergescopes(mod, scopes) - #failed, tot = py.std.doctest.testmod(mod, verbose=1) - #if failed: - # py.test.fail("doctest %s: %s failed out of %s" %( - # self.fspath, failed, tot)) + return "\n".join(l) -class PyPyReSTChecker(ReSTChecker): +class PyPyDocfileTests(DocfileTests): DoctestText = PyPyDoctestText class Directory(Directory): - ReSTChecker = PyPyReSTChecker - def run(self): - l = super(Directory, self).run() - if 'statistic' in l: - l.remove('statistic') - return l + DocfileTests = PyPyDocfileTests + def recfilter(self, path): + if path.basename == "statistic": + return False + return super(Directory, self).recfilter(path) try: from docutils.parsers.rst import directives, states, roles + from py.__.rest.directive import register_linkrole except ImportError: pass else: Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Mon Oct 6 12:14:08 2008 @@ -198,6 +198,7 @@ (e.g. the object space) and any variables you have created on the PyPy prompt with the prefix ``w_``:: + .. >>> import py ; py.test.skip("skipchunk") >>>> a = 123 >>>> *** Entering interpreter-level console *** Modified: pypy/dist/pypy/interpreter/test/test_appinterp.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_appinterp.py (original) +++ pypy/dist/pypy/interpreter/test/test_appinterp.py Mon Oct 6 12:14:08 2008 @@ -22,7 +22,7 @@ (): y y """) - assert str(excinfo).find('y y') != -1 + assert str(excinfo.value).find('y y') != -1 def test_simple_applevel(space): app = appdef("""app(x,y): Modified: pypy/dist/pypy/interpreter/test/test_code.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_code.py (original) +++ pypy/dist/pypy/interpreter/test/test_code.py Mon Oct 6 12:14:08 2008 @@ -8,9 +8,14 @@ space = gettestobjspace() cls.space = space if py.test.config.option.runappdirect: - cls.w_file = space.wrap(__file__[:-1]) + filename = __file__ else: - cls.w_file = space.wrap("None<%s" % gateway.__file__[:-1]) + filename = gateway.__file__ + + if filename[-3:] != '.py': + filename = filename[:-1] + + cls.w_file = space.wrap(filename) def test_attributes(self): def f(): pass Modified: pypy/dist/pypy/tool/ansi_mandelbrot.py ============================================================================== --- pypy/dist/pypy/tool/ansi_mandelbrot.py (original) +++ pypy/dist/pypy/tool/ansi_mandelbrot.py Mon Oct 6 12:14:08 2008 @@ -1,6 +1,6 @@ import sys -from py.__.misc.terminal_helper import ansi_print, get_terminal_width +from py.__.io.terminalwriter import ansi_print, get_terminal_width """ Black 0;30 Dark Gray 1;30 Modified: pypy/dist/pypy/tool/ansi_print.py ============================================================================== --- pypy/dist/pypy/tool/ansi_print.py (original) +++ pypy/dist/pypy/tool/ansi_print.py Mon Oct 6 12:14:08 2008 @@ -4,7 +4,7 @@ import sys -from py.__.misc.terminal_helper import ansi_print +from py.__.io.terminalwriter import ansi_print from pypy.tool.ansi_mandelbrot import Driver class AnsiLog: Modified: pypy/dist/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/appsupport.py (original) +++ pypy/dist/pypy/tool/pytest/appsupport.py Mon Oct 6 12:14:08 2008 @@ -10,8 +10,8 @@ class AppCode(object): def __init__(self, space, pycode): - self.code = space.unwrap(space.getattr(pycode, space.wrap('co_code'))) - self.raw = self.code + self.code = pycode + self.raw = pycode self.w_file = space.getattr(pycode, space.wrap('co_filename')) self.name = space.getattr(pycode, space.wrap('co_name')) self.firstlineno = space.unwrap(space.getattr(pycode, space.wrap('co_firstlineno'))) @@ -29,6 +29,9 @@ return py.code.Source(self.path.read(mode="rU")) fullsource = property(fullsource, None, None, "Full source of AppCode") + def getargs(self): + return self.raw.co_varnames[:self.raw.co_argcount] + class AppFrame(py.code.Frame): def __init__(self, space, pyframe): @@ -60,6 +63,15 @@ def is_true(self, w_value): return self.space.is_true(w_value) + def getargs(self): + space = self.space + retval = [] + for arg in self.code.getargs(): + w_val = space.getitem(self.w_locals, space.wrap(arg)) + retval.append((arg, w_val)) + return retval + + class AppExceptionInfo(py.code.ExceptionInfo): """An ExceptionInfo object representing an app-level exception.""" Modified: pypy/dist/pypy/tool/pytest/pypy_test_failure_demo.py ============================================================================== --- pypy/dist/pypy/tool/pytest/pypy_test_failure_demo.py (original) +++ pypy/dist/pypy/tool/pytest/pypy_test_failure_demo.py Mon Oct 6 12:14:08 2008 @@ -22,5 +22,9 @@ raises(SyntaxError, int, "hello") def app_test_raises_doesnt(): - raises(ValueError, int, 3) + raises(ValueError, int, 3) + +def app_test_skip(): + skip("skipped test") + Modified: pypy/dist/pypy/tool/test/test_conftest1.py ============================================================================== --- pypy/dist/pypy/tool/test/test_conftest1.py (original) +++ pypy/dist/pypy/tool/test/test_conftest1.py Mon Oct 6 12:14:08 2008 @@ -2,39 +2,24 @@ import py innertest = py.magic.autopath().dirpath('conftest1_innertest.py') -from py.__.test.terminal.terminal import TerminalSession -from py.__.test.outcome import Passed, Failed, Skipped +from py.__.test.testing import suptest -class TestPyPyTests: +class TestPyPyTests(suptest.InlineSession): def test_select_interplevel(self): - config = py.test.config._reparse([innertest, '-k', 'interplevel']) - session = TerminalSession(config, py.std.sys.stdout) - session.main() - l = session.getitemoutcomepairs(Passed) - assert len(l) == 2 - for item in l: - assert item[0].name in ('test_something', 'test_method') - #item = l[0][0] - #assert item.name == 'test_one' - l = session.getitemoutcomepairs(Skipped) - assert len(l) == 2 - for item in l: - assert item[0].name in ('app_test_something', 'test_method_app') + sorter = self.parse_and_run("-k", "interplevel", innertest) + passed, skipped, failed = sorter.listoutcomes() + assert len(passed) == 2 + assert not skipped and not failed + for repevent in passed: + assert repevent.colitem.name in ('test_something', 'test_method') def test_select_applevel(self): - config = py.test.config._reparse([innertest, '-k', 'applevel']) - session = TerminalSession(config, py.std.sys.stdout) - session.main() - l = session.getitemoutcomepairs(Passed) - assert len(l) == 2 - for item in l: - assert item[0].name in ('app_test_something', 'test_method_app') - #item = l[0][0] - #assert item.name == 'test_one' - l = session.getitemoutcomepairs(Skipped) - assert len(l) == 2 - for item in l: - assert item[0].name in ('test_something', 'test_method') + sorter = self.parse_and_run("-k", "applevel", innertest) + passed, skipped, failed = sorter.listoutcomes() + assert len(passed) == 2 + assert not skipped and not failed + for repevent in passed: + assert repevent.colitem.name in ('app_test_something', 'test_method_app') def XXX_test_appdirect(self): config = py.test.config._reparse([innertest, Modified: pypy/dist/pypy/tool/test/test_pytestsupport.py ============================================================================== --- pypy/dist/pypy/tool/test/test_pytestsupport.py (original) +++ pypy/dist/pypy/tool/test/test_pytestsupport.py Mon Oct 6 12:14:08 2008 @@ -117,7 +117,7 @@ tdir = udir.ensure("t", dir=True) dest = tdir.join("test_expect.py") dest.write(source) - col = conftest.Module(dest) + col = conftest.Module(dest, config="dummy") result = col.run() assert len(result) == 1 @@ -138,7 +138,7 @@ dest = udir.join("test_expect_safefilename.py") dest.write(source) from pypy import conftest - col = conftest.Module(dest) + col = conftest.Module(dest, config="dummy") methcol = col.join('ExpectTestOne').join('()').join('test_one') name = 'test_expect_safefilename_ExpectTestOne_paren_test_one.py' assert methcol.safe_filename() == name From cfbolz at codespeak.net Mon Oct 6 13:15:53 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 13:15:53 +0200 (CEST) Subject: [pypy-svn] r58624 - pypy/branch/2.5-features/pypy/interpreter/astcompiler Message-ID: <20081006111553.4BBDE16A192@codespeak.net> Author: cfbolz Date: Mon Oct 6 13:15:51 2008 New Revision: 58624 Modified: pypy/branch/2.5-features/pypy/interpreter/astcompiler/pyassem.py Log: (xoraxax, cfbolz): Fix annotation problem. Modified: pypy/branch/2.5-features/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/branch/2.5-features/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/branch/2.5-features/pypy/interpreter/astcompiler/pyassem.py Mon Oct 6 13:15:51 2008 @@ -51,8 +51,7 @@ self.argcount = self.argcount - 1 def checkFlag(self, flag): - if self.flags & flag: - return 1 + return self.flags & flag def setFreeVars(self, names): self.freevars = list(names) From pedronis at codespeak.net Mon Oct 6 13:42:30 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 6 Oct 2008 13:42:30 +0200 (CEST) Subject: [pypy-svn] r58625 - pypy/build/bot2/pypybuildbot Message-ID: <20081006114230.85EC8169E23@codespeak.net> Author: pedronis Date: Mon Oct 6 13:42:30 2008 New Revision: 58625 Modified: pypy/build/bot2/pypybuildbot/steps.py Log: (hpk, pedronis) now that pypy-pytrunk has been merged the nightly runner can be switched to run tests for pypy dist trying a dry-run Modified: pypy/build/bot2/pypybuildbot/steps.py ============================================================================== --- pypy/build/bot2/pypybuildbot/steps.py (original) +++ pypy/build/bot2/pypybuildbot/steps.py Mon Oct 6 13:42:30 2008 @@ -57,12 +57,12 @@ "-p.buildbot-sourcedata", "."], )) self.addStep(source.SVN(baseURL="http://codespeak.net/svn/pypy/", - defaultBranch="branch/pypy-pytrunk")) + defaultBranch="dist")) self.addStep(shell.ShellCommand( description="pytest", command=["python", "testrunner/runner.py", "--logfile=testrun.log", - "--config=pypy/testrunner_cfg.py", + "--config=pypy/testrunner_cfg.py", "--dry-run", "--config=~/machine_cfg.py", "--root=pypy"], logfiles={'pytestLog': 'testrun.log'}, From cfbolz at codespeak.net Mon Oct 6 13:49:23 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 13:49:23 +0200 (CEST) Subject: [pypy-svn] r58626 - pypy/branch/2.5-features/pypy/objspace/test Message-ID: <20081006114923.45659169E2F@codespeak.net> Author: cfbolz Date: Mon Oct 6 13:49:20 2008 New Revision: 58626 Modified: pypy/branch/2.5-features/pypy/objspace/test/test_descriptor.py Log: (arigo around, cfbolz): Modified: pypy/branch/2.5-features/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/branch/2.5-features/pypy/objspace/test/test_descriptor.py (original) +++ pypy/branch/2.5-features/pypy/objspace/test/test_descriptor.py Mon Oct 6 13:49:20 2008 @@ -50,22 +50,11 @@ raises(TypeError, hex, inst) assert A.seen == [1,2,3,4] -class TestDesciprtorOnStd: +class AppTestDescriptorOnStd: def test_hash(self): - class A: + class A(object): pass hash(A()) - class B: - def __eq__(self, other): pass - raises(TypeError, hash, B()) - class C: - def __cmp__(self, other): pass - raises(TypeError, "hash(C())") - - #class D: - # def __hash__(self): - # return 23L - #raises(TypeError, hash, D()) class E: def __hash__(self): From arigo at codespeak.net Mon Oct 6 13:50:36 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 13:50:36 +0200 (CEST) Subject: [pypy-svn] r58627 - pypy/branch/2.5-merge/pypy/interpreter/test Message-ID: <20081006115036.CA4F5169E36@codespeak.net> Author: arigo Date: Mon Oct 6 13:50:34 2008 New Revision: 58627 Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_interpreter.py Log: (iko, arigo) Another test for MAKE_CLOSURE. Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_interpreter.py Mon Oct 6 13:50:34 2008 @@ -231,6 +231,17 @@ assert self.codetest(code, 'g', [12, {}]) == () assert self.codetest(code, 'g', [12, {3:1}]) == (3,) + def test_closure(self): + code = ''' + def f(x, y): + def g(u, v): + return u - v + 7*x + return g + def callme(x, u, v): + return f(x, 123)(u, v) + ''' + assert self.codetest(code, 'callme', [1, 2, 3]) == 6 + def test_list_comprehension(self): code = ''' def f(): From arigo at codespeak.net Mon Oct 6 13:51:15 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 13:51:15 +0200 (CEST) Subject: [pypy-svn] r58628 - pypy/branch/2.5-merge/pypy/objspace/flow/test Message-ID: <20081006115115.09C3E169E43@codespeak.net> Author: arigo Date: Mon Oct 6 13:51:12 2008 New Revision: 58628 Removed: pypy/branch/2.5-merge/pypy/objspace/flow/test/test___import__.py Log: (cfbolz) kill pointless test From arigo at codespeak.net Mon Oct 6 13:54:28 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 13:54:28 +0200 (CEST) Subject: [pypy-svn] r58629 - pypy/branch/2.5-features Message-ID: <20081006115428.BB08016A061@codespeak.net> Author: arigo Date: Mon Oct 6 13:54:24 2008 New Revision: 58629 Removed: pypy/branch/2.5-features/ Log: Kill! Use the 2.5-merge branch now. From hpk at codespeak.net Mon Oct 6 14:04:11 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 6 Oct 2008 14:04:11 +0200 (CEST) Subject: [pypy-svn] r58630 - pypy/dist/pypy Message-ID: <20081006120411.9FA0116A009@codespeak.net> Author: hpk Date: Mon Oct 6 14:04:10 2008 New Revision: 58630 Modified: pypy/dist/pypy/conftest.py Log: dont use deprecated run() method. Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Mon Oct 6 14:04:10 2008 @@ -484,12 +484,11 @@ class Directory(py.test.collect.Directory): - def run(self): - # hack to exclude lib/ctypes/ - if self.fspath == rootdir.join('lib', 'ctypes', 'test'): + def consider_dir(self, path, usefilters=True): + if path == rootdir.join("lib", "ctypes", "test"): py.test.skip("These are the original ctypes tests.\n" "You can try to run them with 'pypy-c runtests.py'.") - return py.test.collect.Directory.run(self) + return super(Directory, self).consider_dir(path, usefilters=usefilters) def recfilter(self, path): # disable recursion in symlinked subdirectories From pedronis at codespeak.net Mon Oct 6 14:15:48 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 6 Oct 2008 14:15:48 +0200 (CEST) Subject: [pypy-svn] r58635 - pypy/build/bot2/pypybuildbot Message-ID: <20081006121548.7A95B169FDA@codespeak.net> Author: pedronis Date: Mon Oct 6 14:15:47 2008 New Revision: 58635 Modified: pypy/build/bot2/pypybuildbot/steps.py Log: real run now Modified: pypy/build/bot2/pypybuildbot/steps.py ============================================================================== --- pypy/build/bot2/pypybuildbot/steps.py (original) +++ pypy/build/bot2/pypybuildbot/steps.py Mon Oct 6 14:15:47 2008 @@ -62,7 +62,7 @@ description="pytest", command=["python", "testrunner/runner.py", "--logfile=testrun.log", - "--config=pypy/testrunner_cfg.py", "--dry-run", + "--config=pypy/testrunner_cfg.py", "--config=~/machine_cfg.py", "--root=pypy"], logfiles={'pytestLog': 'testrun.log'}, From xoraxax at codespeak.net Mon Oct 6 14:21:18 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 6 Oct 2008 14:21:18 +0200 (CEST) Subject: [pypy-svn] r58636 - pypy/dist/pypy/config Message-ID: <20081006122118.43D4C16A05B@codespeak.net> Author: xoraxax Date: Mon Oct 6 14:21:17 2008 New Revision: 58636 Modified: pypy/dist/pypy/config/translationoption.py Log: Enable listcomp optimization by default. Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Mon Oct 6 14:21:17 2008 @@ -146,7 +146,7 @@ "When true, look for and special-case the sequence of " "operations that results from a list comprehension and " "attempt to pre-allocate the list", - default=False, + default=True, cmdline='--listcompr'), IntOption("withsmallfuncsets", "Represent groups of less funtions than this as indices into an array", @@ -327,6 +327,7 @@ for word in words: if word == 'nobackendopt': config.translation.backendopt.suggest(none=True) + config.translation.suggest(list_comprehension_operations=False) elif word == 'lowinline': config.translation.backendopt.suggest(inline_threshold= DEFL_LOW_INLINE_THRESHOLD) @@ -334,7 +335,6 @@ config.translation.backendopt.suggest(remove_asserts=True) elif word == 'extraopts': config.translation.suggest(withsmallfuncsets=5) - config.translation.suggest(list_comprehension_operations=True) else: raise ValueError(word) From hpk at codespeak.net Mon Oct 6 14:22:46 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 6 Oct 2008 14:22:46 +0200 (CEST) Subject: [pypy-svn] r58637 - pypy/branch/pypy-pytrunk Message-ID: <20081006122246.57D2B16A05B@codespeak.net> Author: hpk Date: Mon Oct 6 14:22:45 2008 New Revision: 58637 Removed: pypy/branch/pypy-pytrunk/ Log: another branch bites the has-been-merged dust. From arigo at codespeak.net Mon Oct 6 14:23:23 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 14:23:23 +0200 (CEST) Subject: [pypy-svn] r58638 - pypy/branch/2.5-merge/pypy/module/__builtin__/test Message-ID: <20081006122323.7B28616A05B@codespeak.net> Author: arigo Date: Mon Oct 6 14:23:22 2008 New Revision: 58638 Modified: pypy/branch/2.5-merge/pypy/module/__builtin__/test/test_import.py Log: Fix syntax for 2.4. Modified: pypy/branch/2.5-merge/pypy/module/__builtin__/test/test_import.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/__builtin__/test/test_import.py (original) +++ pypy/branch/2.5-merge/pypy/module/__builtin__/test/test_import.py Mon Oct 6 14:23:22 2008 @@ -307,8 +307,9 @@ assert relative_e.string.inpackage == 1 def test_future_relative_import_error_when_in_non_package(self): - def imp(): - from .string import inpackage + exec """def imp(): + from .string import inpackage + """ raises(ValueError, imp) def test_universal_newlines(self): From arigo at codespeak.net Mon Oct 6 14:34:16 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 14:34:16 +0200 (CEST) Subject: [pypy-svn] r58639 - pypy/branch/2.5-merge/pypy/module/_sre Message-ID: <20081006123416.F006216A01C@codespeak.net> Author: arigo Date: Mon Oct 6 14:34:16 2008 New Revision: 58639 Modified: pypy/branch/2.5-merge/pypy/module/_sre/app_sre.py Log: (iko, arigo) These helpers moved to another module. Modified: pypy/branch/2.5-merge/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_sre/app_sre.py (original) +++ pypy/branch/2.5-merge/pypy/module/_sre/app_sre.py Mon Oct 6 14:34:16 2008 @@ -75,8 +75,8 @@ filter = repl if not callable(repl) and "\\" in repl: # handle non-literal strings ; hand it over to the template compiler - import sre - filter = sre._subx(self, repl) + import re + filter = re._subx(self, repl) state = _sre._State(string, 0, sys.maxint, self.flags) sublist = [] @@ -242,8 +242,8 @@ def expand(self, template): """Return the string obtained by doing backslash substitution and resolving group references on template.""" - import sre - return sre._expand(self.re, self, template) + import re + return re._expand(self.re, self, template) def groups(self, default=None): """Returns a tuple containing all the subgroups of the match. The From hpk at codespeak.net Mon Oct 6 14:37:09 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 6 Oct 2008 14:37:09 +0200 (CEST) Subject: [pypy-svn] r58640 - pypy/dist/lib-python Message-ID: <20081006123709.70A4516A078@codespeak.net> Author: hpk Date: Mon Oct 6 14:37:08 2008 New Revision: 58640 Modified: pypy/dist/lib-python/conftest.py Log: fix lib-python conftest and port to py/trunk Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Mon Oct 6 14:37:08 2008 @@ -45,9 +45,9 @@ default=str(pypyexecpath), help="to use together with -C to specify the path to the " "compiled version of pypy, by default expected in pypy/bin/pypy-c"), - Option('-E', '--extracttests', action="store_true", - default=False, dest="extracttests", - help="try to extract single tests and run them via py.test/PyPy"), + #Option('-E', '--extracttests', action="store_true", + # default=False, dest="extracttests", + # help="try to extract single tests and run them via py.test/PyPy"), Option('-T', '--timeout', action="store", type="string", default="100mp", dest="timeout", help="fail a test module after the given timeout. " @@ -193,7 +193,7 @@ finally: sys.stdout = oldsysout - def run(self): + def runtest(self): # XXX integrate this into InterceptedRunModule # but we want a py.test refactoring towards # more autonomy of colitems regarding @@ -215,7 +215,7 @@ print output, # -class InterceptedRunModule(py.test.collect.Module): +class XXXInterceptedRunModule(py.test.collect.Module): """ special handling for tests with a proper 'def test_main(): ' definition invoking test_support.run_suite or run_unittest (XXX add support for test_support.run_doctest). @@ -252,25 +252,18 @@ testitem = AppDocTestModule(name, parent=self, w_module=w_module) self.name2item[name] = testitem - def run(self): + def collect(self): self._prepare() - keys = self.name2item.keys() - keys.sort(lambda x,y: cmp(x.lower(), y.lower())) - return keys - - def join(self, name): - self._prepare() - try: - return self.name2item[name] - except KeyError: - pass + items = self.name2item.items() + items.sort() + return items class AppDocTestModule(py.test.collect.Item): def __init__(self, name, parent, w_module): super(AppDocTestModule, self).__init__(name, parent) self.w_module = w_module - def run(self): + def runtest(self): py.test.skip("application level doctest modules not supported yet.") class AppTestCaseMethod(py.test.collect.Item): @@ -279,7 +272,7 @@ self.space = gettestobjspace() self.w_method = w_method - def run(self): + def runtest(self): space = self.space filename = str(self.fspath) callex(space, set_argv, space, space.wrap(filename)) @@ -766,16 +759,17 @@ cache[x.basename] = x return cache.get(name, None) - def run(self): - return [x.basename for x in testmap] - - def join(self, name): - regrtest = self.get(name) - if regrtest is not None: - if not option.extracttests: - return RunFileExternal(name, parent=self, regrtest=regrtest) - else: - return InterceptedRunModule(name, self, regrtest) + def collect(self): + l = [] + for x in testmap: + name = x.basename + regrtest = self.get(name) + if regrtest is not None: + #if option.extracttests: + # l.append(InterceptedRunModule(name, self, regrtest)) + #else: + l.append(RunFileExternal(name, parent=self, regrtest=regrtest)) + return l Directory = RegrDirectory @@ -923,7 +917,7 @@ regrrun, regrrun_verbosity, fspath.purebasename) return cmd - def run(self): + def runtest(self): """ invoke a subprocess running the test file via PyPy. record its output into the 'result/user at host' subdirectory. (we might want to create subdirectories for From pedronis at codespeak.net Mon Oct 6 14:44:20 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 6 Oct 2008 14:44:20 +0200 (CEST) Subject: [pypy-svn] r58642 - pypy/dist/pypy/doc Message-ID: <20081006124420.3004116A07D@codespeak.net> Author: pedronis Date: Mon Oct 6 14:44:19 2008 New Revision: 58642 Modified: pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/index.txt Log: update docs to point at the buildbot-driven testrun summaries Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Mon Oct 6 14:44:19 2008 @@ -102,11 +102,10 @@ **Note that running all the tests takes a very long time, and enormous amounts of memory if you are trying to run them all in the same process; test_all.py is only suitable to run a -subset of them at a time.** To run them all we have an -`autotest driver`_ that executes the tests directory by -directory and produces pages like the following one: +subset of them at a time.** To run them all daily we have a BuildBot based +setup, a summary of its results can be seen at: - http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html + http://wyvern.cs.uni-duesseldorf.de:8099/summary .. _`if PyPy works on your machine/platform`: index.html#status .. _`autotest driver`: http://codespeak.net/pipermail/pypy-dev/2006q3/003273.html Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Mon Oct 6 14:44:19 2008 @@ -86,8 +86,7 @@ them. Linux 64-bit machines are supported (though it may also take some time before we notice and fix bugs). -PyPy's own tests, daily updated, `on Linux`_, `on Windows`_ - and `on built pypy-c`_. +PyPy's own tests `summary`_, daily updated, run through BuildBot infrastructure. `Nightly builds and benchmarks`_ of PyPy to C, CLI and LLVM (PowerPC machine). @@ -179,9 +178,7 @@ .. _`bytecode interpreter`: interpreter.html .. _`EU reports`: index-report.html .. _`Technical reports`: index-report.html -.. _`on Linux`: http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html -.. _`on Windows`: http://scottdial.com/pypytest/summary.html -.. _`on built pypy-c`: http://wyvern.cs.uni-duesseldorf.de/~fijal/pypy-c-tests/ +.. _`summary`: http://wyvern.cs.uni-duesseldorf.de:8099/summary .. _`ideas for PyPy related projects`: project-ideas.html .. _`Nightly builds and benchmarks`: http://tuatara.cs.uni-duesseldorf.de/benchmark.html .. _`directory reference`: From cfbolz at codespeak.net Mon Oct 6 14:52:44 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 14:52:44 +0200 (CEST) Subject: [pypy-svn] r58643 - pypy/branch/2.5-merge/lib-python/modified-2.5.1/test Message-ID: <20081006125244.BA1B616A00E@codespeak.net> Author: cfbolz Date: Mon Oct 6 14:52:44 2008 New Revision: 58643 Added: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_codecs.py - copied, changed from r58628, pypy/branch/2.5-merge/lib-python/2.5.1/test/test_codecs.py Log: port a cpython bug that is failing on pypy Copied: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_codecs.py (from r58628, pypy/branch/2.5-merge/lib-python/2.5.1/test/test_codecs.py) ============================================================================== --- pypy/branch/2.5-merge/lib-python/2.5.1/test/test_codecs.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_codecs.py Mon Oct 6 14:52:44 2008 @@ -2,7 +2,7 @@ from test import test_support import unittest import codecs -import sys, StringIO, _testcapi +import sys, StringIO class Queue(object): """ @@ -1120,6 +1120,7 @@ if encoding not in broken_incremental_coders: # check incremental decoder/encoder (fetched via the Python # and C API) and iterencode()/iterdecode() + import _testcapi try: encoder = codecs.getincrementalencoder(encoding)() cencoder = _testcapi.codec_incrementalencoder(encoding) From arigo at codespeak.net Mon Oct 6 14:53:08 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 14:53:08 +0200 (CEST) Subject: [pypy-svn] r58644 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081006125308.85B9416A00E@codespeak.net> Author: arigo Date: Mon Oct 6 14:53:08 2008 New Revision: 58644 Modified: pypy/branch/2.5-merge/pypy/objspace/std/ropeunicodeobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_unicodeobject.py pypy/branch/2.5-merge/pypy/objspace/std/unicodeobject.py Log: (iko, arigo) Fix for running the tests on top of a 16bits-unicode CPython. Added an explicit test (another one was obscurely failing). Modified: pypy/branch/2.5-merge/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/ropeunicodeobject.py Mon Oct 6 14:53:08 2008 @@ -862,7 +862,7 @@ # code2 is lost if code2 >= 0xDC00 and code2 <= 0xDFFF: code = (((code & 0x03FF) << 10) | (code2 & 0x03FF)) + 0x00010000 - result.extend(["U", + result.extend(['\\', "U", hexdigits[(code >> 28) & 0xf], hexdigits[(code >> 24) & 0xf], hexdigits[(code >> 20) & 0xf], Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_unicodeobject.py Mon Oct 6 14:53:08 2008 @@ -267,6 +267,11 @@ def test_float_from_unicode(self): assert float(u'123.456e89') == float('123.456e89') + def test_repr_16bits(self): + # this used to fail when run on a CPython host with 16-bit unicodes + s = repr(u'\U00101234') + assert s == "u'\\U00101234'" + def test_repr(self): for ustr in [u"", u"a", u"'", u"\'", u"\"", u"\t", u"\\", u'', u'a', u'"', u'\'', u'\"', u'\t', u'\\', u"'''\"", Modified: pypy/branch/2.5-merge/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/unicodeobject.py Mon Oct 6 14:53:08 2008 @@ -933,7 +933,7 @@ code2 = ord(ch2) if code2 >= 0xDC00 and code2 <= 0xDFFF: code = (((code & 0x03FF) << 10) | (code2 & 0x03FF)) + 0x00010000 - result.extend(["U", + result.extend(['\\', "U", hexdigits[(code >> 28) & 0xf], hexdigits[(code >> 24) & 0xf], hexdigits[(code >> 20) & 0xf], From pedronis at codespeak.net Mon Oct 6 14:53:13 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 6 Oct 2008 14:53:13 +0200 (CEST) Subject: [pypy-svn] r58645 - pypy/build/bot2 Message-ID: <20081006125313.C76FE16A05A@codespeak.net> Author: pedronis Date: Mon Oct 6 14:53:13 2008 New Revision: 58645 Added: pypy/build/bot2/wyvern_buildbot.css (contents, props changed) pypy/build/bot2/wyvern_robots.txt (contents, props changed) Log: version control this buildbot files for the wyvern setup too Added: pypy/build/bot2/wyvern_buildbot.css ============================================================================== --- (empty file) +++ pypy/build/bot2/wyvern_buildbot.css Mon Oct 6 14:53:13 2008 @@ -0,0 +1,78 @@ +a:visited { + color: #800080; +} + +td.Event, td.BuildStep, td.Activity, td.Change, td.Time, td.Builder { + border-top: 1px solid; + border-right: 1px solid; +} + +td.box { + border: 1px solid; +} + +/* Activity states */ +.offline { + background-color: red; +} +.idle { + background-color: white; +} +.waiting { + background-color: yellow; +} +.building { + background-color: yellow; +} + +/* LastBuild, BuildStep states */ +.success { + background-color: #72ff75; +} +.failure { + background-color: red; +} +.warnings { + background-color: #ff8000; +} +.exception { + background-color: #c000c0; +} +.start,.running { + background-color: yellow; +} + +/* grid styles */ + +table.Grid { + border-collapse: collapse; +} + +table.Grid tr td { + padding: 0.2em; + margin: 0px; + text-align: center; +} + +table.Grid tr td.title { + font-size: 90%; + border-right: 1px gray solid; + border-bottom: 1px gray solid; +} + +table.Grid tr td.sourcestamp { + font-size: 90%; +} + +table.Grid tr td.builder { + text-align: right; + font-size: 90%; +} + +table.Grid tr td.build { + border: 1px gray solid; +} + +div.footer { + font-size: 80%; +} Added: pypy/build/bot2/wyvern_robots.txt ============================================================================== --- (empty file) +++ pypy/build/bot2/wyvern_robots.txt Mon Oct 6 14:53:13 2008 @@ -0,0 +1,10 @@ +User-agent: * +Disallow: /waterfall +Disallow: /summary +Disallow: /builders +Disallow: /changes +Disallow: /buildslaves +Disallow: /schedulers +Disallow: /one_line_per_build +Disallow: /one_box_per_builder +Disallow: /xmlrpc From cfbolz at codespeak.net Mon Oct 6 14:55:59 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 14:55:59 +0200 (CEST) Subject: [pypy-svn] r58646 - pypy/branch/2.5-merge/pypy/module/_codecs/test Message-ID: <20081006125559.B1E8416A032@codespeak.net> Author: cfbolz Date: Mon Oct 6 14:55:59 2008 New Revision: 58646 Modified: pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py Log: _this_ ports a failing cpython test. the last checkin made a failing import local to where it is used so that at least some tests can be run. Modified: pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py Mon Oct 6 14:55:59 2008 @@ -297,3 +297,44 @@ raises(TypeError, "\\x0y".decode, "unicode-escape", "test.baddecodereturn1") raises(TypeError, "\\Uffffeeee".decode, "unicode-escape", "test.baddecodereturn1") raises(TypeError, "\\uyyyy".decode, "raw-unicode-escape", "test.baddecodereturn1") + + def test_cpy_bug1175396(self): + py.test.skip('utf-7 decoder bug') + import codecs, StringIO + s = [ + '<%!--===================================================\r\n', + ' BLOG index page: show recent articles,\r\n', + ' today\'s articles, or articles of a specific date.\r\n', + '========================================================--%>\r\n', + '<%@inputencoding="ISO-8859-1"%>\r\n', + '<%@pagetemplate=TEMPLATE.y%>\r\n', + '<%@import=import frog.util, frog%>\r\n', + '<%@import=import frog.objects%>\r\n', + '<%@import=from frog.storageerrors import StorageError%>\r\n', + '<%\r\n', + '\r\n', + 'import logging\r\n', + 'log=logging.getLogger("Snakelets.logger")\r\n', + '\r\n', + '\r\n', + 'user=self.SessionCtx.user\r\n', + 'storageEngine=self.SessionCtx.storageEngine\r\n', + '\r\n', + '\r\n', + 'def readArticlesFromDate(date, count=None):\r\n', + ' entryids=storageEngine.listBlogEntries(date)\r\n', + ' entryids.reverse() # descending\r\n', + ' if count:\r\n', + ' entryids=entryids[:count]\r\n', + ' try:\r\n', + ' return [ frog.objects.BlogEntry.load(storageEngine, date, Id) for Id in entryids ]\r\n', + ' except StorageError,x:\r\n', + ' log.error("Error loading articles: "+str(x))\r\n', + ' self.abort("cannot load articles")\r\n', + ] + stream = StringIO.StringIO("".join(s).encode("utf7")) + assert "aborrt" not in stream.getvalue() + reader = codecs.getreader("utf7")(stream) + for (i, line) in enumerate(reader): + assert line == s[i] + From cfbolz at codespeak.net Mon Oct 6 14:58:17 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 14:58:17 +0200 (CEST) Subject: [pypy-svn] r58647 - pypy/branch/2.5-merge/pypy/module/_codecs/test Message-ID: <20081006125817.3F5E916A06C@codespeak.net> Author: cfbolz Date: Mon Oct 6 14:58:16 2008 New Revision: 58647 Modified: pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py Log: bah, nonsense Modified: pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py Mon Oct 6 14:58:16 2008 @@ -299,7 +299,7 @@ raises(TypeError, "\\uyyyy".decode, "raw-unicode-escape", "test.baddecodereturn1") def test_cpy_bug1175396(self): - py.test.skip('utf-7 decoder bug') + skip('utf-7 decoder bug') import codecs, StringIO s = [ '<%!--===================================================\r\n', From arigo at codespeak.net Mon Oct 6 15:06:44 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 15:06:44 +0200 (CEST) Subject: [pypy-svn] r58649 - pypy/branch/2.5-merge/pypy/module/__builtin__/test Message-ID: <20081006130644.5416E169E43@codespeak.net> Author: arigo Date: Mon Oct 6 15:06:43 2008 New Revision: 58649 Modified: pypy/branch/2.5-merge/pypy/module/__builtin__/test/test_classobj.py Log: (iko, arigo) Fix test. Modified: pypy/branch/2.5-merge/pypy/module/__builtin__/test/test_classobj.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/__builtin__/test/test_classobj.py (original) +++ pypy/branch/2.5-merge/pypy/module/__builtin__/test/test_classobj.py Mon Oct 6 15:06:43 2008 @@ -757,6 +757,6 @@ class Z: def __del__(self): pass - Z().__del__ = lambda self: None + Z().__del__ = lambda : None finally: warnings.simplefilter('default', RuntimeWarning) From fijal at codespeak.net Mon Oct 6 15:19:51 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 6 Oct 2008 15:19:51 +0200 (CEST) Subject: [pypy-svn] r58650 - in pypy/branch/2.5-merge/pypy/rlib: . test Message-ID: <20081006131951.0745C169F8D@codespeak.net> Author: fijal Date: Mon Oct 6 15:19:50 2008 New Revision: 58650 Modified: pypy/branch/2.5-merge/pypy/rlib/rsocket.py pypy/branch/2.5-merge/pypy/rlib/test/test_rsocket.py Log: (fijal, jlg) Dummy support for recv_into on rlib level Modified: pypy/branch/2.5-merge/pypy/rlib/rsocket.py ============================================================================== --- pypy/branch/2.5-merge/pypy/rlib/rsocket.py (original) +++ pypy/branch/2.5-merge/pypy/rlib/rsocket.py Mon Oct 6 15:19:50 2008 @@ -822,6 +822,10 @@ rffi.keep_buffer_alive_until_here(raw_buf, gc_buf) raise self.error_handler() + def recvinto(self, rwbuffer, nbytes, flags=0): + buf = self.recv(nbytes, flags) + rwbuffer.setslice(0, buf) + def recvfrom(self, buffersize, flags=0): """Like recv(buffersize, flags) but also return the sender's address.""" Modified: pypy/branch/2.5-merge/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/branch/2.5-merge/pypy/rlib/test/test_rsocket.py (original) +++ pypy/branch/2.5-merge/pypy/rlib/test/test_rsocket.py Mon Oct 6 15:19:50 2008 @@ -103,6 +103,29 @@ s1.close() s2.close() +def test_socketpair_recvinto(): + class Buffer: + def setslice(self, start, string): + self.x = string + + def as_str(self): + return self.x + + if sys.platform == "win32": + py.test.skip('No socketpair on Windows') + s1, s2 = socketpair() + buf = Buffer() + s1.sendall('?') + s2.recvinto(buf, 1) + assert buf.as_str() == '?' + count = s2.send('x'*99) + assert 1 <= count <= 99 + s1.recvinto(buf, 100) + assert buf.as_str() == 'x'*count + s1.close() + s2.close() + + def test_simple_tcp(): import thread sock = RSocket() From witulski at codespeak.net Mon Oct 6 15:20:53 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Mon, 6 Oct 2008 15:20:53 +0200 (CEST) Subject: [pypy-svn] r58651 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081006132053.D297C16857B@codespeak.net> Author: witulski Date: Mon Oct 6 15:20:53 2008 New Revision: 58651 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: JMP/JNE BUG(maybe) fixed (need to sub the length of the JMP opcode to the displacement) enter_next_block: Constants will be changed to GenVars Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Mon Oct 6 15:20:53 2008 @@ -178,7 +178,7 @@ _CMP_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, 1, "\x81", 3, None, 7) _CMP_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x39", 3, None, None) # FIXME: rexB is set - _CMP_8REG_IMM8 = make_two_operand_instr( 0, 0, 0, 0, "\x82", 3, None, 7) + _CMP_8REG_IMM8 = make_two_operand_instr( 0, 0, 0, None, "\x80", 3, None, 7) _DEC_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xFF", 3, None, 1) _INC_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xFF", 3, None, 0) @@ -233,6 +233,7 @@ method(op1, op2) def CMP(self, op1, op2): + #import pdb;pdb.set_trace() method = getattr(self, "_CMP"+op1.to_string()+op2.to_string()) method(op1, op2) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Mon Oct 6 15:20:53 2008 @@ -148,13 +148,14 @@ # def op_int_invert(self, gv_x): # return self.mc.NOT(gv_x) - + #FIXME: can only jump 32bit + # -6 : length of the jne instruction def jump_if_true(self, gv_condition, args_for_jump_gv): targetbuilder = Builder() self.mc.CMP(gv_condition, Immediate32(0)) displ = self.calc_32bit_displacement(self.mc.tell(),targetbuilder.mc.tell()) - self.mc.JNE(displ) + self.mc.JNE(displ-6) #targetbuilder.come_from(self.mc, 'JNE') return targetbuilder @@ -210,14 +211,16 @@ #FIXME: uses 32bit displ # if the label is greater than 32bit # it must be in a register - def finish_and_goto(self, outputargs_gv, target): + # -5 length of the jmp instruction + def finish_and_goto(self, outputargs_gv, target): + import pdb;pdb.set_trace() self._open() #gv_x = self.allocate_register() #self.mc.MOV(gv_x,Immediate64(target.startaddr)) #self.mc.JMP(gv_x) displ = self.calc_32bit_displacement(self.mc.tell(),target.startaddr) - self.mc.JMP(displ) + self.mc.JMP(displ-5) #self.mc.RET() @@ -235,11 +238,15 @@ def end(self): pass - #TODO: Implementation + #TODO: args_gv muste be a list of unique GenVars def enter_next_block(self, args_gv): - #print "WriteMe: enter_next_block" - L = Label(self.mc.tell(), [], 0) - #print "DEBUG2:",L.startaddr + # move constants into an register + for i in range(len(args_gv)): + if isinstance(args_gv[i],model.GenConst): + gv_x = self.allocate_register() + self.mc.MOV(gv_x, argsv_gv[i]) + args_gv[i] = gv_x + L = Label(self.mc.tell(), args_gv, 0) return L def _close(self): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Mon Oct 6 15:20:53 2008 @@ -142,7 +142,7 @@ res = fp(84,1) assert res == 42 - def test_mul_im32(self): + def test_mul_imm32(self): rgenop = self.RGenOp() mul_function = make_mul_imm(rgenop,200) fnptr = self.cast(mul_function,1) @@ -278,35 +278,35 @@ res = fnptr(-4,0) assert res == 0 - def test__equal(self): + def test_equal(self): cmp_function = make_cmp(self.RGenOp(), "int_eq",42) fnptr = self.cast(cmp_function,1) res = fnptr(42) assert res == 1 res = fnptr(23) assert res == 0 - cmp_function = make_cmp(self.RGenOp(), "int_eq") - fnptr = self.cast(cmp_function,2) - res = fnptr(3,4) # 3==4? - assert res == 0 # false - res = fnptr(4,3) - assert res == 0 - res = fnptr(4,4) - assert res == 1 - res = fnptr(4,0) - assert res == 0 - res = fnptr(-4,0) - assert res == 0 - res = fnptr(184467440737095516,184467440737095516) - assert res == 1 - res = fnptr(252,-4) - assert res == 0 - res = fnptr(-4,252) - assert res == 0 - res = fnptr(244,756) - assert res == 0 - res = fnptr(-1,9223372036854775807) #FFFF.... != 7FFF... - assert res == 0 + #cmp_function = make_cmp(self.RGenOp(), "int_eq") + #fnptr = self.cast(cmp_function,2) + #res = fnptr(3,4) # 3==4? + #assert res == 0 # false + #res = fnptr(4,3) + #assert res == 0 + #res = fnptr(4,4) + #assert res == 1 + #res = fnptr(4,0) + #assert res == 0 + #res = fnptr(-4,0) + #assert res == 0 + #res = fnptr(184467440737095516,184467440737095516) + #assert res == 1 + #res = fnptr(252,-4) + #assert res == 0 + #res = fnptr(-4,252) + #assert res == 0 + #res = fnptr(244,756) + #assert res == 0 + #res = fnptr(-1,9223372036854775807) #FFFF.... != 7FFF... + #assert res == 0 def test_not_equal(self): cmp_function = make_cmp(self.RGenOp(), "int_ne") @@ -450,7 +450,7 @@ test_dummy_direct = skip test_largedummy_direct = skip test_branching_direct = skip - test_goto_direct = skip## + ##test_goto_direct = skip## test_if_direct = skip test_switch_direct = skip test_large_switch_direct = skip From arigo at codespeak.net Mon Oct 6 15:29:52 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 15:29:52 +0200 (CEST) Subject: [pypy-svn] r58652 - pypy/branch/2.5-merge/lib-python/modified-2.5.1/test Message-ID: <20081006132952.CC8D1169FDC@codespeak.net> Author: arigo Date: Mon Oct 6 15:29:52 2008 New Revision: 58652 Added: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py - copied, changed from r58645, pypy/branch/2.5-merge/lib-python/2.5.1/test/test_itertools.py Log: (iko, arigo) Kill the changes done to the previous modified test_itertools and start again from the CPython version. Only a few changes in the test are necessary. Copied: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py (from r58645, pypy/branch/2.5-merge/lib-python/2.5.1/test/test_itertools.py) ============================================================================== --- pypy/branch/2.5-merge/lib-python/2.5.1/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py Mon Oct 6 15:29:52 2008 @@ -193,8 +193,11 @@ zip('abc', 'def')) self.assertEqual([pair for pair in izip('abc', 'def')], zip('abc', 'def')) - ids = map(id, izip('abc', 'def')) - self.assertEqual(min(ids), max(ids)) + # the following test deals with a specific implementation detail, + # that izip "reuses" the SAME tuple object each time when it can; + # it does not apply correctly to pypy, so I'm commenting it -- AM + # ids = map(id, izip('abc', 'def')) + # self.assertEqual(min(ids), max(ids)) ids = map(id, list(izip('abc', 'def'))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) @@ -280,11 +283,11 @@ self.assertRaises(ValueError, islice, xrange(10), 1, -5, -1) self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1) self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0) - self.assertRaises(ValueError, islice, xrange(10), 'a') - self.assertRaises(ValueError, islice, xrange(10), 'a', 1) - self.assertRaises(ValueError, islice, xrange(10), 1, 'a') - self.assertRaises(ValueError, islice, xrange(10), 'a', 1, 1) - self.assertRaises(ValueError, islice, xrange(10), 1, 'a', 1) + self.assertRaises((TypeError, ValueError), islice, xrange(10), 'a') + self.assertRaises((TypeError, ValueError), islice, xrange(10), 'a', 1) + self.assertRaises((TypeError, ValueError), islice, xrange(10), 1, 'a') + self.assertRaises((TypeError, ValueError), islice, xrange(10), 'a', 1, 1) + self.assertRaises((TypeError, ValueError), islice, xrange(10), 1, 'a', 1) self.assertEqual(len(list(islice(count(), 1, 10, sys.maxint))), 1) def test_takewhile(self): @@ -359,9 +362,11 @@ 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')) + # XXX why?? the following test would pass too if type(a)('def') + # just returned iter('abc')... + #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(xrange(2000), 3) From fijal at codespeak.net Mon Oct 6 15:34:35 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 6 Oct 2008 15:34:35 +0200 (CEST) Subject: [pypy-svn] r58653 - in pypy/branch/2.5-merge/pypy/module/_socket: . test Message-ID: <20081006133435.4CF8016A025@codespeak.net> Author: fijal Date: Mon Oct 6 15:34:34 2008 New Revision: 58653 Modified: pypy/branch/2.5-merge/pypy/module/_socket/interp_socket.py pypy/branch/2.5-merge/pypy/module/_socket/test/test_sock_app.py Log: (fijal, jlg) recv_into, recvfrom_into in socket objects. Modified: pypy/branch/2.5-merge/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_socket/interp_socket.py (original) +++ pypy/branch/2.5-merge/pypy/module/_socket/interp_socket.py Mon Oct 6 15:34:34 2008 @@ -304,6 +304,34 @@ space.wrap('Timeout value out of range')) self.settimeout(timeout) settimeout_w.unwrap_spec = ['self', ObjSpace, W_Root] + + def recv_into_w(self, space, w_buffer, nbytes=0, flags=0): + rwbuffer = space.rwbuffer_w(w_buffer) + lgt = rwbuffer.getlength() + if nbytes == 0 or nbytes > lgt: + nbytes = lgt + try: + return space.wrap(self.recvinto(rwbuffer, nbytes, flags)) + except SocketError, e: + raise converted_error(space, e) + + recv_into_w.unwrap_spec = ['self', ObjSpace, W_Root, int, int] + + def recvfrom_into_w(self, space, w_buffer, nbytes=0, flags=0): + rwbuffer = space.rwbuffer_w(w_buffer) + lgt = rwbuffer.getlength() + if nbytes == 0 or nbytes > lgt: + nbytes = lgt + try: + readlgt, addr = self.recvfrom_into(rwbuffer, nbytes, flags) + if addr: + w_addr = addr.as_object(space) + else: + w_addr = space.w_None + return space.newtuple([space.wrap(readlgt), w_addr]) + except SocketError, e: + raise converted_error(space, e) + recvfrom_into_w.unwrap_spec = ['self', ObjSpace, W_Root, int, int] def shutdown_w(self, space, how): """shutdown(flag) @@ -390,7 +418,7 @@ accept bind close connect connect_ex dup fileno getpeername getsockname getsockopt gettimeout listen makefile recv recvfrom send sendall sendto setblocking -setsockopt settimeout shutdown _reuse _drop +setsockopt settimeout shutdown _reuse _drop recv_into recvfrom_into """.split() # Remove non-implemented methods for name in ('dup',): Modified: pypy/branch/2.5-merge/pypy/module/_socket/test/test_sock_app.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_socket/test/test_sock_app.py (original) +++ pypy/branch/2.5-merge/pypy/module/_socket/test/test_sock_app.py Mon Oct 6 15:34:34 2008 @@ -507,7 +507,36 @@ # done cli.close() t.close() - + + def test_recv_into(self): + import socket + import array + MSG = 'dupa was here\n' + cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + cli.connect(self.serv.getsockname()) + conn, addr = self.serv.accept() + buf = buffer(MSG) + conn.send(buf) + buf = array.array('c', ' '*1024) + nbytes = cli.recv_into(buf) + assert nbytes == len(MSG) + msg = buf.tostring()[:len(MSG)] + assert msg == MSG + + def test_recvfrom_into(self): + import socket + import array + MSG = 'dupa was here\n' + cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + cli.connect(self.serv.getsockname()) + conn, addr = self.serv.accept() + buf = buffer(MSG) + conn.send(buf) + buf = array.array('c', ' '*1024) + nbytes, addr = cli.recvfrom_into(buf) + assert nbytes == len(MSG) + msg = buf.tostring()[:len(MSG)] + assert msg == MSG class AppTestErrno: def setup_class(cls): @@ -527,3 +556,4 @@ assert errno.errorcode[e.args[0]].endswith("EINVAL") assert isinstance(e.args[1], str) + From fijal at codespeak.net Mon Oct 6 15:34:50 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 6 Oct 2008 15:34:50 +0200 (CEST) Subject: [pypy-svn] r58654 - pypy/branch/2.5-merge/pypy/rlib Message-ID: <20081006133450.E10F716A025@codespeak.net> Author: fijal Date: Mon Oct 6 15:34:50 2008 New Revision: 58654 Modified: pypy/branch/2.5-merge/pypy/rlib/rsocket.py Log: oops, forgot to check it in in last commit Modified: pypy/branch/2.5-merge/pypy/rlib/rsocket.py ============================================================================== --- pypy/branch/2.5-merge/pypy/rlib/rsocket.py (original) +++ pypy/branch/2.5-merge/pypy/rlib/rsocket.py Mon Oct 6 15:34:50 2008 @@ -825,6 +825,7 @@ def recvinto(self, rwbuffer, nbytes, flags=0): buf = self.recv(nbytes, flags) rwbuffer.setslice(0, buf) + return len(buf) def recvfrom(self, buffersize, flags=0): """Like recv(buffersize, flags) but also return the sender's @@ -855,6 +856,11 @@ rffi.keep_buffer_alive_until_here(raw_buf, gc_buf) raise self.error_handler() + def recvfrom_into(self, rwbuffer, nbytes, flags=0): + buf, addr = self.recvfrom(nbytes, flags) + rwbuffer.setslice(0, buf) + return len(buf), addr + def send_raw(self, dataptr, length, flags=0): """Send data from a CCHARP buffer.""" res = -1 From arigo at codespeak.net Mon Oct 6 15:45:37 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 15:45:37 +0200 (CEST) Subject: [pypy-svn] r58655 - in pypy/branch/2.5-merge/pypy/module/itertools: . test Message-ID: <20081006134537.1BB5F169F41@codespeak.net> Author: arigo Date: Mon Oct 6 15:45:36 2008 New Revision: 58655 Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Log: (iko, arigo) Make these subclassable. *Of course* there are now CPython tests that rely on this. Bah. Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py Mon Oct 6 15:45:36 2008 @@ -47,7 +47,6 @@ yield n n += 1 """) -W_Count.typedef.acceptable_as_base_class = False class W_Repeat(Wrappable): @@ -97,7 +96,6 @@ for i in xrange(times): yield object """) -W_Repeat.typedef.acceptable_as_base_class = False class W_TakeWhile(Wrappable): @@ -143,7 +141,6 @@ else: break """) -W_TakeWhile.typedef.acceptable_as_base_class = False class W_DropWhile(Wrappable): @@ -194,7 +191,6 @@ for x in iterable: yield x """) -W_DropWhile.typedef.acceptable_as_base_class = False class _IFilterBase(Wrappable): @@ -246,7 +242,6 @@ if predicate(x): yield x """) -W_IFilter.typedef.acceptable_as_base_class = False class W_IFilterFalse(_IFilterBase): reverse = True @@ -272,7 +267,6 @@ if not predicate(x): yield x """) -W_IFilterFalse.typedef.acceptable_as_base_class = False class W_ISlice(Wrappable): def __init__(self, space, w_iterable, w_startstop, args_w): @@ -360,7 +354,6 @@ internal structure has been flattened (for example, a multi-line report may list a name field on every third line). """) -W_ISlice.typedef.acceptable_as_base_class = False class W_Chain(Wrappable): @@ -433,7 +426,6 @@ for element in it: yield element """) -W_Chain.typedef.acceptable_as_base_class = False class W_IMap(Wrappable): _error_name = "imap" @@ -503,7 +495,6 @@ yield function(*args) """) -W_IMap.typedef.acceptable_as_base_class = False class W_IZip(W_IMap): @@ -538,7 +529,6 @@ result = [i.next() for i in iterables] yield tuple(result) """) -W_IZip.typedef.acceptable_as_base_class = False class W_Cycle(Wrappable): @@ -604,7 +594,6 @@ for element in saved: yield element """) -W_Cycle.typedef.acceptable_as_base_class = False class W_StarMap(Wrappable): @@ -645,7 +634,6 @@ while True: yield function(*iterable.next()) """) -W_StarMap.typedef.acceptable_as_base_class = False def tee(space, w_iterable, n=2): @@ -832,7 +820,6 @@ groups.append(list(g)) # Store group iterator as a list uniquekeys.append(k) """) -W_GroupBy.typedef.acceptable_as_base_class = False class W_GroupByIterator(Wrappable): def __init__(self, space, index, groupby): Modified: pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Mon Oct 6 15:45:36 2008 @@ -565,38 +565,3 @@ ] for method in methods: assert method.__doc__ - - def test_subclassing(self): - import itertools - # Although (mostly) implemented as classes, the itertools functions - # should probably not be subclassable. They are in CPython but - # subclassing them is insane if you ask me (and really forbidden - # by the docs, that pretend that they are functions). - import sys - if '__pypy__' not in sys.builtin_module_names: - skip("itertools types are subclassable in CPython") - iterables = [ - itertools.chain, - itertools.count, - itertools.cycle, - itertools.dropwhile, - itertools.groupby, - itertools.ifilter, - itertools.ifilterfalse, - itertools.imap, - itertools.islice, - itertools.izip, - itertools.repeat, - itertools.starmap, - itertools.takewhile, - itertools.tee, - ] - for cls in iterables: - try: - class A(cls): - pass - except TypeError: - pass - else: - assert False, "Subclassing should fail." - From arigo at codespeak.net Mon Oct 6 15:54:45 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 15:54:45 +0200 (CEST) Subject: [pypy-svn] r58656 - in pypy/branch/2.5-merge/pypy/module/itertools: . test Message-ID: <20081006135445.9D7AA169F1B@codespeak.net> Author: arigo Date: Mon Oct 6 15:54:45 2008 New Revision: 58656 Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Log: (iko, arigo) Add a repr to 'count' and 'repeat'. Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py Mon Oct 6 15:54:45 2008 @@ -23,6 +23,10 @@ return self.space.wrap(c) + def repr_w(self): + s = 'count(%d)' % (self.c,) + return self.space.wrap(s) + def W_Count___new__(space, w_subtype, firstval=0): return space.wrap(W_Count(space, firstval)) @@ -32,6 +36,7 @@ __new__ = interp2app(W_Count___new__, unwrap_spec=[ObjSpace, W_Root, int]), __iter__ = interp2app(W_Count.iter_w, unwrap_spec=['self']), next = interp2app(W_Count.next_w, unwrap_spec=['self']), + __repr__ = interp2app(W_Count.repr_w, unwrap_spec=['self']), __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() @@ -72,6 +77,14 @@ def iter_w(self): return self.space.wrap(self) + def repr_w(self): + objrepr = self.space.str_w(self.space.repr(self.w_obj)) + if self.counting: + s = 'repeat(%s, %d)' % (objrepr, self.count) + else: + s = 'repeat(%s)' % (objrepr,) + return self.space.wrap(s) + def W_Repeat___new__(space, w_subtype, w_obj, w_times=None): return space.wrap(W_Repeat(space, w_obj, w_times)) @@ -80,6 +93,7 @@ __new__ = interp2app(W_Repeat___new__, unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root]), __iter__ = interp2app(W_Repeat.iter_w, unwrap_spec=['self']), next = interp2app(W_Repeat.next_w, unwrap_spec=['self']), + __repr__ = interp2app(W_Repeat.repr_w, unwrap_spec=['self']), __doc__ = """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 Modified: pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Mon Oct 6 15:54:45 2008 @@ -29,6 +29,14 @@ raises(OverflowError, itertools.count, sys.maxint + 1) + def test_count_repr(self): + import itertools + + it = itertools.count(123) + assert repr(it) == 'count(123)' + it.next() + assert repr(it) == 'count(124)' + def test_repeat(self): import itertools @@ -66,6 +74,21 @@ raises(OverflowError, itertools.repeat, None, sys.maxint + 1) + def test_repeat_repr(self): + import itertools + + it = itertools.repeat('foobar') + assert repr(it) == "repeat('foobar')" + it.next() + assert repr(it) == "repeat('foobar')" + + it = itertools.repeat('foobar', 10) + assert repr(it) == "repeat('foobar', 10)" + it.next() + assert repr(it) == "repeat('foobar', 9)" + list(it) + assert repr(it) == "repeat('foobar', 0)" + def test_takewhile(self): import itertools From arigo at codespeak.net Mon Oct 6 16:05:31 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 16:05:31 +0200 (CEST) Subject: [pypy-svn] r58657 - in pypy/branch/2.5-merge/pypy/module/itertools: . test Message-ID: <20081006140531.B316C169FFD@codespeak.net> Author: arigo Date: Mon Oct 6 16:05:29 2008 New Revision: 58657 Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Log: (iko, arigo) Redo an optimization that CPython tests for. Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py Mon Oct 6 16:05:29 2008 @@ -678,9 +678,16 @@ """ if n < 0: raise OperationError(space.w_ValueError, space.wrap("n must be >= 0")) - - tee_state = TeeState(space, w_iterable) - iterators_w = [space.wrap(W_TeeIterable(space, tee_state)) for x in range(n)] + + myiter = space.interpclass_w(w_iterable) + if isinstance(myiter, W_TeeIterable): # optimization only + tee_state = myiter.tee_state + iterators_w = [w_iterable] * n + for i in range(1, n): + iterators_w[i] = space.wrap(W_TeeIterable(space, tee_state)) + else: + tee_state = TeeState(space, w_iterable) + iterators_w = [space.wrap(W_TeeIterable(space, tee_state)) for x in range(n)] return space.newtuple(iterators_w) tee.unwrap_spec = [ObjSpace, W_Root, int] Modified: pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Mon Oct 6 16:05:29 2008 @@ -439,6 +439,22 @@ raises(ValueError, itertools.tee, [], -1) raises(TypeError, itertools.tee, [], None) + def test_tee_optimization(self): + import itertools + + a, b = itertools.tee(iter('foobar')) + c, d = itertools.tee(b) + assert c is b + assert a is not c + assert a is not d + assert c is not d + res = list(a) + assert res == list('foobar') + res = list(c) + assert res == list('foobar') + res = list(d) + assert res == list('foobar') + def test_groupby(self): import itertools From hpk at codespeak.net Mon Oct 6 16:10:15 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 6 Oct 2008 16:10:15 +0200 (CEST) Subject: [pypy-svn] r58658 - pypy/dist/lib-python Message-ID: <20081006141015.1E0E916A004@codespeak.net> Author: hpk Date: Mon Oct 6 16:10:14 2008 New Revision: 58658 Modified: pypy/dist/lib-python/conftest.py Log: (pedronis,hpk) major cleanup of lib-python/conftest.py: * strike out all code related to writing result information to the "testresult" dir * you now use "py.test --pypy=execname" if you want to run a lib-python test on top of pypy-c. * strike some other non-used code. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Mon Oct 6 16:10:14 2008 @@ -20,9 +20,6 @@ from pypy.tool.pytest import appsupport from pypy.tool.pytest.confpath import pypydir, libpythondir, \ regrtestdir, modregrtestdir, testresultdir -from pypy.tool.pytest.result import Result, ResultFromMime - -pypyexecpath = pypydir.join('bin', 'pypy-c') dist_rsync_roots = ['.', '../pypy', '../py'] @@ -30,32 +27,15 @@ # Interfacing/Integrating with py.test's collection process # -# XXX no nice way to implement a --listpassing py.test option?! -#option = py.test.addoptions("compliance testing options", -# py.test.Option('-L', '--listpassing', action="store", default=None, -# type="string", dest="listpassing", -# help="just display the list of expected-to-pass tests.") - Option = py.test.config.Option option = py.test.config.addoptions("compliance testing options", - Option('-C', '--compiled', action="store_true", - default=False, dest="use_compiled", - help="use a compiled version of pypy"), - Option('--compiled-pypy', action="store", type="string", dest="pypy_executable", - default=str(pypyexecpath), - help="to use together with -C to specify the path to the " - "compiled version of pypy, by default expected in pypy/bin/pypy-c"), - #Option('-E', '--extracttests', action="store_true", - # default=False, dest="extracttests", - # help="try to extract single tests and run them via py.test/PyPy"), Option('-T', '--timeout', action="store", type="string", default="100mp", dest="timeout", help="fail a test module after the given timeout. " "specify in seconds or 'NUMmp' aka Mega-Pystones"), - Option('--resultdir', action="store", type="string", - default=None, dest="resultdir", - help="directory under which to store results in USER at HOST subdirs", - ), + Option('--pypy', action="store", type="string", + dest="pypy", help="use given pypy executable to run lib-python tests. " + "This will run the tests directly (i.e. not through py.py)") ) def gettimeout(): @@ -496,7 +476,7 @@ RegrTest('test_gl.py', enabled=False, dumbtest=1), RegrTest('test_glob.py', enabled=True, core=True), - RegrTest('test_global.py', enabled=True, core=True, compiler='ast'), + RegrTest('test_global.py', enabled=True, core=True), RegrTest('test_grammar.py', enabled=True, core=True), RegrTest('test_grp.py', enabled=False), #rev 10840: ImportError: grp @@ -786,23 +766,6 @@ # "unknown" for them return 'unknown' -def getexecutable(_cache={}): - execpath = py.path.local(option.pypy_executable) - if not _cache: - text = execpath.sysexec('-c', - 'import sys; ' - 'print sys.version; ' - 'print sys.pypy_svn_url; ' - 'print sys.pypy_translation_info; ') - lines = [line.strip() for line in text.split('\n')] - assert len(lines) == 4 and lines[3] == '' - assert lines[2].startswith('{') and lines[2].endswith('}') - info = eval(lines[2]) - info['version'] = lines[0] - info['rev'] = eval(lines[1])[1] - _cache.update(info) - return execpath, _cache - class RunFileExternal(py.test.collect.Module): def __init__(self, name, parent, regrtest): super(RunFileExternal, self).__init__(name, parent) @@ -822,28 +785,6 @@ return ReallyRunFileExternal(name, parent=self) -def ensuretestresultdir(): - resultdir = option.resultdir - default_place = False - if resultdir is not None: - resultdir = py.path.local(option.resultdir) - else: - if option.use_compiled: - return None - default_place = True - resultdir = testresultdir - - if not resultdir.check(dir=1): - if default_place: - py.test.skip("""'testresult' directory not found. - To run tests in reporting mode (without -E), you first have to - check it out as follows: - svn co http://codespeak.net/svn/pypy/testresult %s""" % ( - testresultdir, )) - else: - py.test.skip("'%s' test result dir not found" % resultdir) - return resultdir - # # testmethod: # invoking in a seprate process: py.py TESTFILE @@ -854,23 +795,6 @@ import getpass class ReallyRunFileExternal(py.test.collect.Item): - _resultcache = None - def _haskeyword(self, keyword): - if keyword == 'core': - return self.parent.regrtest.core - if keyword not in ('error', 'ok', 'timeout'): - return super(ReallyRunFileExternal, self).haskeyword(keyword) - if self._resultcache is None: - from pypy.tool.pytest.overview import ResultCache - self.__class__._resultcache = rc = ResultCache() - rc.parselatest() - result = self._resultcache.getlatestrelevant(self.fspath.purebasename) - if not result: return False - if keyword == 'timeout': return result.istimeout() - if keyword == 'error': return result.iserror() - if keyword == 'ok': return result.isok() - assert False, "should not be there" - def getinvocation(self, regrtest): fspath = regrtest.getfspath() python = sys.executable @@ -881,11 +805,7 @@ regr_script = pypydir.join('tool', 'pytest', 'run-script', 'regrverbose.py') - if option.use_compiled: - execpath, info = getexecutable() pypy_options = [] - if regrtest.compiler: - pypy_options.append('--compiler=%s' % regrtest.compiler) pypy_options.extend( ['--withmod-%s' % mod for mod in regrtest.usemodules]) sopt = " ".join(pypy_options) @@ -902,7 +822,10 @@ regrrun_verbosity = '0' TIMEOUT = gettimeout() - if option.use_compiled: + if option.pypy: + execpath = py.path.local.sysfind(option.pypy) + if not execpath: + raise LookupError("could not find executable %r" %(option.pypy,)) cmd = "%s %s %s %s" %( execpath, regrrun, regrrun_verbosity, fspath.purebasename) @@ -926,84 +849,37 @@ i am afraid. """ regrtest = self.parent.regrtest - result = self.getresult(regrtest) - testresultdir = ensuretestresultdir() - if testresultdir is not None: - resultdir = testresultdir.join(result['userhost']) - assert resultdir.ensure(dir=1) - - fn = resultdir.join(regrtest.basename).new(ext='.txt') - if result.istimeout(): - if fn.check(file=1): - try: - oldresult = ResultFromMime(fn) - except TypeError: - pass - else: - if not oldresult.istimeout(): - py.test.skip("timed out, not overwriting " - "more interesting non-timeout outcome") - - fn.write(result.repr_mimemessage().as_string(unixfrom=False)) - - if result['exit-status']: + exit_status, test_stdout, test_stderr = self.getresult(regrtest) + if exit_status: time.sleep(0.5) # time for a Ctrl-C to reach us :-) - print >>sys.stdout, result.getnamedtext('stdout') - print >>sys.stderr, result.getnamedtext('stderr') + print >>sys.stdout, test_stdout + print >>sys.stderr, test_stderr py.test.fail("running test failed, see stderr output below") def getstatusouterr(self, cmd): - tempdir = py.path.local.mkdtemp() - try: - stdout = tempdir.join(self.fspath.basename) + '.out' - stderr = tempdir.join(self.fspath.basename) + '.err' - if sys.platform == 'win32': - status = os.system("%s >%s 2>%s" %(cmd, stdout, stderr)) - if status>=0: - status = status - else: - status = 'abnormal termination 0x%x' % status + tempdir = py.test.ensuretemp(self.fspath.basename) + stdout = tempdir.join(self.fspath.basename) + '.out' + stderr = tempdir.join(self.fspath.basename) + '.err' + if sys.platform == 'win32': + status = os.system("%s >%s 2>%s" %(cmd, stdout, stderr)) + if status>=0: + status = status else: - status = os.system("%s >>%s 2>>%s" %(cmd, stdout, stderr)) - if os.WIFEXITED(status): - status = os.WEXITSTATUS(status) - else: - status = 'abnormal termination 0x%x' % status - return status, stdout.read(mode='rU'), stderr.read(mode='rU') - finally: - tempdir.remove() + status = 'abnormal termination 0x%x' % status + else: + status = os.system("%s >>%s 2>>%s" %(cmd, stdout, stderr)) + if os.WIFEXITED(status): + status = os.WEXITSTATUS(status) + else: + status = 'abnormal termination 0x%x' % status + return status, stdout.read(mode='rU'), stderr.read(mode='rU') def getresult(self, regrtest): cmd = self.getinvocation(regrtest) - result = Result() - fspath = regrtest.getfspath() - result['fspath'] = str(fspath) - result['pypy-revision'] = getrev(pypydir) - if option.use_compiled: - execpath, info = getexecutable() - result['pypy-revision'] = info['rev'] - result['executable'] = execpath.basename - for key, value in info.items(): - if key == 'rev': - continue - result['executable-%s' % key] = str(value) - else: - result['executable'] = 'py.py' - result['options'] = regrtest.getoptions() - result['timeout'] = gettimeout() - result['startdate'] = time.ctime() - starttime = time.time() - - # really run the test in a sub process exit_status, test_stdout, test_stderr = self.getstatusouterr(cmd) - timedout = test_stderr.rfind(26*"=" + "timedout" + 26*"=") != -1 if not timedout: timedout = test_stderr.rfind("KeyboardInterrupt") != -1 - result['execution-time'] = time.time() - starttime - result.addnamedtext('stdout', test_stdout) - result.addnamedtext('stderr', test_stderr) - outcome = 'OK' expectedpath = regrtest.getoutputpath() if not exit_status: @@ -1014,19 +890,17 @@ exit_status = 2 res, out, err = py.io.StdCapture.call(reportdiff, expected, test_stdout) outcome = 'ERROUT' - result.addnamedtext('reportdiff', out) + test_stderr += ("-" * 80 + "\n") + out else: if 'FAIL' in test_stdout or 'ERROR' in test_stderr: outcome = 'FAIL' + exit_status = 2 elif timedout: outcome = "T/O" else: outcome = "ERR" - result['exit-status'] = exit_status - result['outcome'] = outcome - return result - + return exit_status, test_stdout, test_stderr # # Sanity check (could be done more nicely too) From hpk at codespeak.net Mon Oct 6 16:17:51 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 6 Oct 2008 16:17:51 +0200 (CEST) Subject: [pypy-svn] r58659 - pypy/dist/lib-python Message-ID: <20081006141751.1C8E116A004@codespeak.net> Author: hpk Date: Mon Oct 6 16:17:50 2008 New Revision: 58659 Modified: pypy/dist/lib-python/conftest.py Log: (pedronis, hpk) more cleanup - strike dead code, use py lib 1.0 collector interface Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Mon Oct 6 16:17:50 2008 @@ -48,220 +48,6 @@ return seconds return float(timeout) -def callex(space, func, *args, **kwargs): - try: - return func(*args, **kwargs) - except OperationError, e: - ilevelinfo = py.code.ExceptionInfo() - if e.match(space, space.w_KeyboardInterrupt): - raise KeyboardInterrupt - appexcinfo = appsupport.AppExceptionInfo(space, e) - if appexcinfo.traceback: - print "appexcinfo.traceback:" - py.std.pprint.pprint(appexcinfo.traceback) - raise py.test.collect.Item.Failed(excinfo=appexcinfo) - raise py.test.collect.Item.Failed(excinfo=ilevelinfo) - -# -# compliance modules where we invoke test_main() usually call into -# test_support.(run_suite|run_doctests) -# we intercept those calls and use the provided information -# for our collection process. This allows us to run all the -# tests one by one. -# - -app = ApplevelClass(''' - #NOT_RPYTHON - - import unittest - from test import test_support - import sys - - def getmethods(suite_or_class): - """ flatten out suites down to TestCase instances/methods. """ - if isinstance(suite_or_class, unittest.TestCase): - res = [suite_or_class] - elif isinstance(suite_or_class, unittest.TestSuite): - res = [] - for x in suite_or_class._tests: - res.extend(getmethods(x)) - elif isinstance(suite_or_class, list): - res = [] - for x in suite_or_class: - res.extend(getmethods(x)) - else: - raise TypeError, "expected TestSuite or TestClass, got %r" %(suite_or_class) - return res - - # - # exported API - # - - def intercept_test_support(): - """ intercept calls to test_support.run_doctest and run_suite. - Return doctestmodules, suites which will hold collected - items from these test_support invocations. - """ - suites = [] - doctestmodules = [] - def hack_run_doctest(module, verbose=None): - doctestmodules.append(module) - test_support.run_doctest = hack_run_doctest - - def hack_run_suite(suite, testclass=None): - suites.append(suite) - test_support.run_suite = hack_run_suite - return suites, doctestmodules - - def collect_intercepted(suites, doctestmodules): - namemethodlist = [] - for method in getmethods(suites): - name = (method.__class__.__name__ + '.' + - method._TestCase__testMethodName) - namemethodlist.append((name, method)) - doctestlist = [] - for mod in doctestmodules: - doctestlist.append((mod.__name__, mod)) - return namemethodlist, doctestlist - - def run_testcase_method(method): - result = method.defaultTestResult() - method.run(result) - if result.errors: - assert len(result.errors) - print result.errors[0][1] - if result.failures: - assert len(result.failures) - print result.failures[0][1] - if result.failures or result.errors: - return 1 - - def set_argv(filename): - sys.argv[:] = ['python', filename] -''') - -intercept_test_support = app.interphook('intercept_test_support') -collect_intercepted = app.interphook('collect_intercepted') -run_testcase_method = app.interphook('run_testcase_method') -set_argv = app.interphook('set_argv') - -def start_intercept(space): - w_suites, w_doctestmodules = space.viewiterable(intercept_test_support(space)) - return w_suites, w_doctestmodules - -def collect_intercept(space, w_suites, w_doctestmodules): - w_result = callex(space, collect_intercepted, space, w_suites, w_doctestmodules) - w_namemethods, w_doctestlist = space.viewiterable(w_result) - return w_namemethods, w_doctestlist - -class SimpleRunItem(py.test.collect.Item): - """ Run a module file and compare its output - to the expected output in the output/ directory. - """ - def call_capture(self, space, func, *args): - regrtest = self.parent.regrtest - oldsysout = sys.stdout - sys.stdout = capturesysout = py.std.cStringIO.StringIO() - try: - try: - res = regrtest.run_file(space) - except: - print capturesysout.getvalue() - raise - else: - return res, capturesysout.getvalue() - finally: - sys.stdout = oldsysout - - def runtest(self): - # XXX integrate this into InterceptedRunModule - # but we want a py.test refactoring towards - # more autonomy of colitems regarding - # their representations - regrtest = self.parent.regrtest - space = gettestobjspace(usemodules=[]) - res, output = self.call_capture(space, regrtest.run_file, space) - - outputpath = regrtest.getoutputpath() - if outputpath: - # we want to compare outputs - # regrtest itself prepends the test_name to the captured output - result = outputpath.purebasename + "\n" + output - expected = outputpath.read(mode='r') - if result != expected: - reportdiff(expected, result) - py.test.fail("output check failed: %s" % (self.fspath.basename,)) - if output: - print output, - -# -class XXXInterceptedRunModule(py.test.collect.Module): - """ special handling for tests with a proper 'def test_main(): ' - definition invoking test_support.run_suite or run_unittest - (XXX add support for test_support.run_doctest). - """ - def __init__(self, name, parent, regrtest): - super(InterceptedRunModule, self).__init__(name, parent) - self.regrtest = regrtest - self.fspath = regrtest.getfspath() - - def _prepare(self): - if hasattr(self, 'name2item'): - return - self.name2item = {} - space = gettestobjspace(usemodules=self.regrtest.usemodules) - if self.regrtest.dumbtest or self.regrtest.getoutputpath(): - self.name2item['output'] = SimpleRunItem('output', self) - return - - tup = start_intercept(space) - self.regrtest.run_file(space) - w_namemethods, w_doctestlist = collect_intercept(space, *tup) - - # setup {name -> wrapped testcase method} - for w_item in space.unpackiterable(w_namemethods): - w_name, w_method = space.viewiterable(w_item) - name = space.str_w(w_name) - testitem = AppTestCaseMethod(name, parent=self, w_method=w_method) - self.name2item[name] = testitem - - # setup {name -> wrapped doctest module} - for w_item in space.unpackiterable(w_doctestlist): - w_name, w_module = space.viewiterable(w_item) - name = space.str_w(w_name) - testitem = AppDocTestModule(name, parent=self, w_module=w_module) - self.name2item[name] = testitem - - def collect(self): - self._prepare() - items = self.name2item.items() - items.sort() - return items - -class AppDocTestModule(py.test.collect.Item): - def __init__(self, name, parent, w_module): - super(AppDocTestModule, self).__init__(name, parent) - self.w_module = w_module - - def runtest(self): - py.test.skip("application level doctest modules not supported yet.") - -class AppTestCaseMethod(py.test.collect.Item): - def __init__(self, name, parent, w_method): - super(AppTestCaseMethod, self).__init__(name, parent) - self.space = gettestobjspace() - self.w_method = w_method - - def runtest(self): - space = self.space - filename = str(self.fspath) - callex(space, set_argv, space, space.wrap(filename)) - #space.call_function(self.w_method) - w_res = callex(space, run_testcase_method, space, self.w_method) - if space.is_true(w_res): - raise AssertionError( - "testcase instance invociation raised errors, see stdoudt") - # ________________________________________________________________________ # # classification of all tests files (this is ongoing work) @@ -753,37 +539,18 @@ Directory = RegrDirectory - -def getrev(path): - try: - return py.path.svnwc(pypydir).info().rev - except (KeyboardInterrupt, SystemExit): - raise - except: - # on windows people not always have 'svn' in their path - # but there are also other kinds of problems that - # could occur and we just default to revision - # "unknown" for them - return 'unknown' - class RunFileExternal(py.test.collect.Module): def __init__(self, name, parent, regrtest): super(RunFileExternal, self).__init__(name, parent) self.regrtest = regrtest self.fspath = regrtest.getfspath() - def tryiter(self, stopitems=()): - # shortcut pre-counting of items - return [] - - def run(self): + def collect(self): if self.regrtest.ismodified(): - return ['modified'] - return ['unmodified'] - - def join(self, name): - return ReallyRunFileExternal(name, parent=self) - + name = 'modified' + else: + name = 'unmodified' + return [ReallyRunFileExternal(name, parent=self)] # # testmethod: From cfbolz at codespeak.net Mon Oct 6 16:28:16 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 16:28:16 +0200 (CEST) Subject: [pypy-svn] r58660 - in pypy/branch/2.5-merge/pypy/module/_codecs: . test Message-ID: <20081006142816.C1657169E0C@codespeak.net> Author: cfbolz Date: Mon Oct 6 16:28:16 2008 New Revision: 58660 Modified: pypy/branch/2.5-merge/pypy/module/_codecs/app_codecs.py pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py Log: (xoraxax, cfbolz, arigo around) bugs in codecs, found by some CPython tests: The second element of the returned tuple (the consumed length) is the length of the _input_ string, not the output string. Design seems a bit strange. No clue how it is for encoders. Modified: pypy/branch/2.5-merge/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_codecs/app_codecs.py (original) +++ pypy/branch/2.5-merge/pypy/module/_codecs/app_codecs.py Mon Oct 6 16:28:16 2008 @@ -66,14 +66,14 @@ """ res = PyUnicode_DecodeRawUnicodeEscape(data, len(data), errors) res = u''.join(res) - return res, len(res) + return res, len(data) def utf_7_decode( data, errors='strict'): """None """ res = PyUnicode_DecodeUTF7(data, len(data), errors) res = u''.join(res) - return res, len(res) + return res, len(data) def unicode_escape_encode( obj, errors='strict'): """None @@ -87,7 +87,7 @@ """ res = PyUnicode_DecodeUnicodeEscape(data, len(data), errors) res = u''.join(res) - return res, len(res) + return res, len(data) def charmap_encode(obj, errors='strict', mapping='latin-1'): @@ -147,7 +147,7 @@ i += unicode_bytes p += unichr(t) res = u''.join(p) - return res, len(res) + return res, len(unistr) # XXX needs error messages when the input is invalid def escape_decode(data, errors='strict'): @@ -197,7 +197,7 @@ res += data[i] i += 1 res = ''.join(res) - return res, len(res) + return res, len(data) def charbuffer_encode( obj, errors='strict'): """None @@ -211,7 +211,7 @@ """ res = PyUnicode_DecodeCharmap(data, len(data), mapping, errors) res = ''.join(res) - return res, len(res) + return res, len(data) def utf_7_encode( obj, errors='strict'): Modified: pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/branch/2.5-merge/pypy/module/_codecs/test/test_codecs.py Mon Oct 6 16:28:16 2008 @@ -299,7 +299,6 @@ raises(TypeError, "\\uyyyy".decode, "raw-unicode-escape", "test.baddecodereturn1") def test_cpy_bug1175396(self): - skip('utf-7 decoder bug') import codecs, StringIO s = [ '<%!--===================================================\r\n', From arigo at codespeak.net Mon Oct 6 16:36:50 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 16:36:50 +0200 (CEST) Subject: [pypy-svn] r58661 - pypy/branch/2.5-merge/lib-python/modified-2.5.1 Message-ID: <20081006143650.6D558169E1B@codespeak.net> Author: arigo Date: Mon Oct 6 16:36:49 2008 New Revision: 58661 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/popen2.py Log: (iko, arigo) Missing import. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/popen2.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/popen2.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/popen2.py Mon Oct 6 16:36:49 2008 @@ -8,6 +8,7 @@ import os import sys +import gc __all__ = ["popen2", "popen3", "popen4"] From arigo at codespeak.net Mon Oct 6 16:37:04 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 16:37:04 +0200 (CEST) Subject: [pypy-svn] r58662 - pypy/branch/2.5-merge/pypy/module/bz2/test Message-ID: <20081006143704.5C808169E1B@codespeak.net> Author: arigo Date: Mon Oct 6 16:37:03 2008 New Revision: 58662 Modified: pypy/branch/2.5-merge/pypy/module/bz2/test/support.py Log: (iko, arigo) Try to call gc.collect() enough times. Modified: pypy/branch/2.5-merge/pypy/module/bz2/test/support.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/bz2/test/support.py (original) +++ pypy/branch/2.5-merge/pypy/module/bz2/test/support.py Mon Oct 6 16:37:03 2008 @@ -2,7 +2,8 @@ def teardown_method(self, fun): from pypy.rpython.lltypesystem import ll2ctypes import gc - gc.collect() - gc.collect() - gc.collect() # to make sure we disallocate buffers + tries = 20 + while tries and ll2ctypes.ALLOCATED: + gc.collect() # to make sure we disallocate buffers + tries -= 1 assert not ll2ctypes.ALLOCATED From arigo at codespeak.net Mon Oct 6 16:38:25 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 16:38:25 +0200 (CEST) Subject: [pypy-svn] r58663 - pypy/branch/2.5-merge/pypy/interpreter/test Message-ID: <20081006143825.6666B169E98@codespeak.net> Author: arigo Date: Mon Oct 6 16:38:24 2008 New Revision: 58663 Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_interpreter.py Log: (iko, arigo) Another (passing) test about the import statement. Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_interpreter.py Mon Oct 6 16:38:24 2008 @@ -249,6 +249,17 @@ ''' assert self.codetest(code, 'f', [])[0] == '_[1]' + def test_import_statement(self): + for x in range(10): + import os + code = ''' + def f(): + for x in range(10): + import os + return os.name + ''' + assert self.codetest(code, 'f', []) == os.name + class TestPyPyInterpreter(TestInterpreter): """Runs the previous test with the pypy parser""" From hpk at codespeak.net Mon Oct 6 16:52:06 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 6 Oct 2008 16:52:06 +0200 (CEST) Subject: [pypy-svn] r58664 - pypy/dist/lib-python Message-ID: <20081006145206.605B2169F07@codespeak.net> Author: hpk Date: Mon Oct 6 16:52:05 2008 New Revision: 58664 Modified: pypy/dist/lib-python/conftest.py Log: allow to specify direct paths for option.pypy Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Mon Oct 6 16:52:05 2008 @@ -590,7 +590,9 @@ TIMEOUT = gettimeout() if option.pypy: - execpath = py.path.local.sysfind(option.pypy) + execpath = py.path.local(option.pypy) + if not execpath.check(): + execpath = py.path.local.sysfind(option.pypy) if not execpath: raise LookupError("could not find executable %r" %(option.pypy,)) cmd = "%s %s %s %s" %( From pedronis at codespeak.net Mon Oct 6 16:53:58 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 6 Oct 2008 16:53:58 +0200 (CEST) Subject: [pypy-svn] r58665 - pypy/build/bot2/pypybuildbot Message-ID: <20081006145358.B14AE169F5E@codespeak.net> Author: pedronis Date: Mon Oct 6 16:53:58 2008 New Revision: 58665 Modified: pypy/build/bot2/pypybuildbot/master.py pypy/build/bot2/pypybuildbot/steps.py Log: (hpk, pedronis) experimental setup for a translating+run cpython test builder Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Mon Oct 6 16:53:58 2008 @@ -25,6 +25,8 @@ pypyOwnTestFactory = pypysteps.PyPyOwnTestFactory() pypyOwnTestFactoryWin = pypysteps.PyPyOwnTestFactory(platform="win32") +pypyTranslatedLibPythonTestFactory = pypysteps.PyPyTranslaledLibPythonTestFactory() + BuildmasterConfig = { 'slavePortnum': slavePortnum, @@ -44,6 +46,12 @@ "builddir": "own-linux-x86-32", "factory": pypyOwnTestFactory }, + {"name": "pypy-c-lib-python-linux-x86-32", + "slavenames": ["wyvern"], + "builddir": "pypy-c-lib-python-linux-x86-32", + "factory": pypyTranslatedLibPythonTestFactory + }, + ], 'buildbotURL': 'http://wyvern.cs.uni-duesseldorf.de:%d/'%(httpPortNumber), Modified: pypy/build/bot2/pypybuildbot/steps.py ============================================================================== --- pypy/build/bot2/pypybuildbot/steps.py (original) +++ pypy/build/bot2/pypybuildbot/steps.py Mon Oct 6 16:53:58 2008 @@ -32,32 +32,53 @@ self.setStatus(None, SUCCESS) self.finished(SUCCESS) +class Translate(shell.ShellCommand): + name = "translate" + description = ["translating"] + descriptionDone = ["translation"] + + command = ["echo", "python", "translate.py", "--batch"] + translationTarget = "targetpypystandalone" + + def __init__(self, translationArgs, targetArgs, + workdir="build/pypy/translator/goal", + *a, **kw): + self.command = (self.command + translationArgs + + [self.translationTarget] + targetArgs) + ShellCommand.__init__(self, workdir, *a, **kw) + + # ________________________________________________________________ def not_first_time(props): first_time = props.getProperty("first-time") return not first_time +def setup_steps(platform, factory): + if platform == "win32": + first_time_check = WindowsFirstTime() + else: + first_time_check = PosixFirstTime() + + factory.addStep(first_time_check) + factory.addStep(CondShellCommand( + description="wcrevert", + cond=not_first_time, + command = ["python", "py/bin/py.svnwcrevert", + "-p.buildbot-sourcedata", "."], + )) + factory.addStep(source.SVN(baseURL="http://codespeak.net/svn/pypy/", + defaultBranch="dist")) + + class PyPyOwnTestFactory(factory.BuildFactory): def __init__(self, *a, **kw): platform = kw.pop('platform', 'linux') factory.BuildFactory.__init__(self, *a, **kw) - if platform == "win32": - first_time_check = WindowsFirstTime() - else: - first_time_check = PosixFirstTime() - - self.addStep(first_time_check) - self.addStep(CondShellCommand( - description="wcrevert", - cond=not_first_time, - command = ["python", "py/bin/py.svnwcrevert", - "-p.buildbot-sourcedata", "."], - )) - self.addStep(source.SVN(baseURL="http://codespeak.net/svn/pypy/", - defaultBranch="dist")) + setup_steps(platform, factory) + self.addStep(shell.ShellCommand( description="pytest", command=["python", "testrunner/runner.py", @@ -67,3 +88,20 @@ "--root=pypy"], logfiles={'pytestLog': 'testrun.log'}, env={"PYTHONPATH": ['.']})) + +class PyPyTranslaledLibPythonTestFactory(factory.BuildFactory): + + def __init__(self, *a, **kw): + platform = kw.pop('platform', 'linux') + factory.BuildFactory.__init__(self, *a, **kw) + + setup_steps(platform, factory) + + self.addStep(Translate(["-O0"], ["-no-allworkingmodules"]) + + self.addStep(shell.ShellCommand( + description="lib-python test", + command=["python", "pypy/test_all.py", + "--pypy=pypy/translator/goal/pypy-c", + "--resultlog=cpython.log"], + logfiles={'pytestLog': 'cpython.log'})) From cfbolz at codespeak.net Mon Oct 6 17:07:21 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 17:07:21 +0200 (CEST) Subject: [pypy-svn] r58666 - in pypy/dist/pypy/translator/tool: . test Message-ID: <20081006150721.A73A1169F25@codespeak.net> Author: cfbolz Date: Mon Oct 6 17:07:20 2008 New Revision: 58666 Added: pypy/dist/pypy/translator/tool/staticsizereport.py (contents, props changed) pypy/dist/pypy/translator/tool/test/test_staticsizereport.py (contents, props changed) Log: (xoraxax, cfbolz): Some helper functions to print statistics about all static data in a database. Added: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Mon Oct 6 17:07:20 2008 @@ -0,0 +1,37 @@ +from __future__ import division + +from pypy.rpython.lltypesystem.lltype import typeOf, _ptr, Ptr +from pypy.rpython.lltypesystem import llmemory +from pypy.rpython.memory.lltypelayout import convert_offset_to_int + +def guess_size(obj): + TYPE = typeOf(obj) + ptr = _ptr(Ptr(TYPE), obj) + if TYPE._is_varsize(): + arrayfld = getattr(TYPE, '_arrayfld', None) + if arrayfld: + length = len(getattr(ptr, arrayfld)) + else: + length = len(ptr) + return convert_offset_to_int(llmemory.sizeof(TYPE, length)) + return convert_offset_to_int(llmemory.sizeof(TYPE)) + + +def group_static_size_by_lltype(database): + totalsize = {} + numobjects = {} + for node in database.globalcontainers(): + obj = node.obj + group = typeOf(obj) + totalsize[group] = totalsize.get(group, 0) + guess_size(obj) + numobjects[group] = numobjects.get(group, 0) + 1 + return totalsize, numobjects + +def print_static_size_by_lltype(database): + totalsize, numobjects = group_static_size_by_lltype(database) + l = [(size, key) for key, size in totalsize.iteritems()] + l.sort() + l.reverse() + for size, key in l: + print key, size, numobjects[key], size / numobjects[key] + Added: pypy/dist/pypy/translator/tool/test/test_staticsizereport.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/tool/test/test_staticsizereport.py Mon Oct 6 17:07:20 2008 @@ -0,0 +1,23 @@ +from pypy.translator.c.test.test_typed import CompilationTestCase +from pypy.translator.tool.staticsizereport import group_static_size_by_lltype + +class TestStaticSizeReport(CompilationTestCase): + def test_simple(self): + class A: + def __init__(self, n): + if n: + self.next = A(n - 1) + else: + self.next = None + self.key = repr(self) + a = A(100) + def f(x): + if x: + return a.key + return a.next.key + func = self.getcompiled(f, [int]) + size, num = group_static_size_by_lltype(self.builder.db) + for key, value in num.iteritems(): + if "staticsizereport.A" in str(key) and "vtable" not in str(key): + assert value == 101 + From pedronis at codespeak.net Mon Oct 6 17:13:22 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 6 Oct 2008 17:13:22 +0200 (CEST) Subject: [pypy-svn] r58667 - pypy/build/bot2/pypybuildbot Message-ID: <20081006151322.3CB32169FAF@codespeak.net> Author: pedronis Date: Mon Oct 6 17:13:21 2008 New Revision: 58667 Modified: pypy/build/bot2/pypybuildbot/steps.py Log: fix some syntax errors still doesn't work Modified: pypy/build/bot2/pypybuildbot/steps.py ============================================================================== --- pypy/build/bot2/pypybuildbot/steps.py (original) +++ pypy/build/bot2/pypybuildbot/steps.py Mon Oct 6 17:13:21 2008 @@ -45,7 +45,7 @@ *a, **kw): self.command = (self.command + translationArgs + [self.translationTarget] + targetArgs) - ShellCommand.__init__(self, workdir, *a, **kw) + shell.ShellCommand.__init__(self, workdir, *a, **kw) # ________________________________________________________________ @@ -77,7 +77,7 @@ platform = kw.pop('platform', 'linux') factory.BuildFactory.__init__(self, *a, **kw) - setup_steps(platform, factory) + setup_steps(platform, self) self.addStep(shell.ShellCommand( description="pytest", @@ -95,9 +95,9 @@ platform = kw.pop('platform', 'linux') factory.BuildFactory.__init__(self, *a, **kw) - setup_steps(platform, factory) + setup_steps(platform, self) - self.addStep(Translate(["-O0"], ["-no-allworkingmodules"]) + self.addStep(Translate(translationArgs=["-O0"], targetArgs=["-no-allworkingmodules"])) self.addStep(shell.ShellCommand( description="lib-python test", From cfbolz at codespeak.net Mon Oct 6 17:19:55 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 17:19:55 +0200 (CEST) Subject: [pypy-svn] r58668 - pypy/dist/pypy/rpython/memory Message-ID: <20081006151955.D14B4169F46@codespeak.net> Author: cfbolz Date: Mon Oct 6 17:19:55 2008 New Revision: 58668 Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py Log: (xoraxax, cfbolz, arigo around) make the lltypelayout size estimate work with rffi types like USHORT. Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypelayout.py (original) +++ pypy/dist/pypy/rpython/memory/lltypelayout.py Mon Oct 6 17:19:55 2008 @@ -22,7 +22,11 @@ def get_layout(TYPE): layout = {} if isinstance(TYPE, lltype.Primitive): - return primitive_to_fmt[TYPE] + try: + return primitive_to_fmt[TYPE] + except KeyError: + from pypy.rpython.lltypesystem import rffi + return rffi.sizeof(TYPE) elif isinstance(TYPE, lltype.Ptr): return "P" elif isinstance(TYPE, lltype.Struct): From fijal at codespeak.net Mon Oct 6 17:46:19 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 6 Oct 2008 17:46:19 +0200 (CEST) Subject: [pypy-svn] r58669 - pypy/build/benchmem/benchmark Message-ID: <20081006154619.56208169FD6@codespeak.net> Author: fijal Date: Mon Oct 6 17:46:18 2008 New Revision: 58669 Modified: pypy/build/benchmem/benchmark/sizes.py Log: fix tests Modified: pypy/build/benchmem/benchmark/sizes.py ============================================================================== --- pypy/build/benchmem/benchmark/sizes.py (original) +++ pypy/build/benchmem/benchmark/sizes.py Mon Oct 6 17:46:18 2008 @@ -1,8 +1,11 @@ +""" checkpointed +""" + glob = 0 def bench_0nothing(iter1): - pass + checkpoint(collect=True) def bench_list_of_None(iter1): l = [None for i in range(iter1)] From fijal at codespeak.net Mon Oct 6 17:47:06 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 6 Oct 2008 17:47:06 +0200 (CEST) Subject: [pypy-svn] r58670 - pypy/build/benchmem Message-ID: <20081006154706.E1B98169FDA@codespeak.net> Author: fijal Date: Mon Oct 6 17:47:06 2008 New Revision: 58670 Modified: pypy/build/benchmem/report.py Log: (fijal, jlg sleeping around) * typo * make it work when result of snapshots is unequal Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Mon Oct 6 17:47:06 2008 @@ -55,9 +55,10 @@ self.begin() for name, results in reader.name2results.items(): row0 = ["num"] + [result.executable for result in results] - numsnapshosts = len(results[0].snapshots) + numsnapshots = min([len(i.snapshots) for i in results]) + rows = [row0] - for i in range(numsnapshosts): + for i in range(numsnapshots): row = [i] for result in results: row.append(result.snapshots[i].private) From fijal at codespeak.net Mon Oct 6 17:47:31 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 6 Oct 2008 17:47:31 +0200 (CEST) Subject: [pypy-svn] r58671 - pypy/build/benchmem Message-ID: <20081006154731.D6685169FD6@codespeak.net> Author: fijal Date: Mon Oct 6 17:47:31 2008 New Revision: 58671 Modified: pypy/build/benchmem/smaps.py Log: (fijal, jlg) make it work on the whole file at once. Modified: pypy/build/benchmem/smaps.py ============================================================================== --- pypy/build/benchmem/smaps.py (original) +++ pypy/build/benchmem/smaps.py Mon Oct 6 17:47:31 2008 @@ -11,27 +11,34 @@ assert self.smapspath.check() def snapshot(self): - f = self.smapspath.open() - headline = f.readline() - while not f.closed: - attrs = [] - while not f.closed: - sizeline = f.readline() - if not sizeline: # EOF - break - parts = sizeline.split() - if len(parts) != 3: - headline = sizeline - break - value = int(parts[1]) - attrs.append(value) + def append_attrs(attrs): attrs = attrs[:6] # not interested in "Referenced" sizes = ",".join(map(str, attrs)) assert sizes self.stream.write("%-24s %s" %(sizes, headline)) - if not sizeline: - break + + f = self.smapspath.open() + lines = f.readlines() f.close() + if not lines: + # XXX + raise py.error.ENOENT + iterlines = iter(lines) + headline = iterlines.next() + try: + while 1: + attrs = [] + while 1: + sizeline = iterlines.next() + parts = sizeline.split() + if len(parts) != 3: + headline = sizeline + break + value = int(parts[1]) + attrs.append(value) + append_attrs(attrs) + except StopIteration: + append_attrs(attrs) self.stream.write(self.SEPSNAPSHOT) self.stream.flush() From fijal at codespeak.net Mon Oct 6 17:47:51 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 6 Oct 2008 17:47:51 +0200 (CEST) Subject: [pypy-svn] r58672 - pypy/build/benchmem/benchmark Message-ID: <20081006154751.BAC3A169FD6@codespeak.net> Author: fijal Date: Mon Oct 6 17:47:51 2008 New Revision: 58672 Added: pypy/build/benchmem/benchmark/appprofiles.py (contents, props changed) Log: Start with app profiles Added: pypy/build/benchmem/benchmark/appprofiles.py ============================================================================== --- (empty file) +++ pypy/build/benchmem/benchmark/appprofiles.py Mon Oct 6 17:47:51 2008 @@ -0,0 +1,25 @@ + +class newstyle(object): + def __init__(self, i, next): + self.i = 100 + i + self.next = next + +class oldstyle(object): + def __init__(self, f, next): + self.f = float(f) + self.next = next + +def bench_allocate_and_throw_away(iter1, iter2): + for i in range(iter1): + next = None + for j in range(iter2): + r = j % 4 + if r == 0: + next = newstyle(j, next) + elif r == 1: + next = oldstyle(j, next) + elif r == 2: + next = (j + 3, next) + elif r == 3: + next = [float(j), next] + From arigo at codespeak.net Mon Oct 6 17:54:46 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 17:54:46 +0200 (CEST) Subject: [pypy-svn] r58673 - pypy/branch/2.5-merge/pypy/interpreter/astcompiler Message-ID: <20081006155446.06EAC169F1B@codespeak.net> Author: arigo Date: Mon Oct 6 17:54:46 2008 New Revision: 58673 Modified: pypy/branch/2.5-merge/pypy/interpreter/astcompiler/__init__.py pypy/branch/2.5-merge/pypy/interpreter/astcompiler/pycodegen.py Log: (iko, arigo) Kill kill kill unused code. Modified: pypy/branch/2.5-merge/pypy/interpreter/astcompiler/__init__.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/astcompiler/__init__.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/astcompiler/__init__.py Mon Oct 6 17:54:46 2008 @@ -1,26 +1 @@ -"""Package for parsing and compiling Python source code - -There are several functions defined at the top level that are imported -from modules contained in the package. - -parse(buf, mode="exec") -> AST - Converts a string containing Python source code to an abstract - syntax tree (AST). The AST is defined in compiler.ast. - -parseFile(path) -> AST - The same as parse(open(path)) - -walk(ast, visitor, verbose=None) - Does a pre-order walk over the ast using the visitor instance. - See compiler.visitor for details. - -compile(source, filename, mode, flags=None, dont_inherit=None) - Returns a code object. A replacement for the builtin compile() function. - -compileFile(filename) - Generates a .pyc file by compiling filename. -""" - -# from transformer import parse, parseFile -# from visitor import walk -# from pycodegen import compile, compileFile +# empty Modified: pypy/branch/2.5-merge/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/astcompiler/pycodegen.py Mon Oct 6 17:54:46 2008 @@ -34,20 +34,6 @@ from pypy.module.__builtin__.__init__ import BUILTIN_TO_INDEX -def compileFile(filename, display=0): - f = open(filename, 'U') - buf = f.read() - f.close() - mod = Module(buf, filename) - try: - mod.compile(display) - except SyntaxError: - raise - else: - f = open(filename + "c", "wb") - mod.dump(f) - f.close() - def compile(source, filename, mode, flags=None, dont_inherit=None): """Replacement for builtin compile() function""" if flags is not None or dont_inherit is not None: @@ -110,21 +96,6 @@ print pprint.pprint(tree) self.code = gen.getCode() - def dump(self, f): - f.write(self.getPycHeader()) - marshal.dump(self.code, f) - - MAGIC = imp.get_magic() - - def getPycHeader(self): - # compile.c uses marshal to write a long directly, with - # calling the interface that would also generate a 1-byte code - # to indicate the type of the value. simplest way to get the - # same effect is to call marshal and then skip the code. - mtime = os.path.getmtime(self.filename) - mtime = struct.pack(' Author: antocuni Date: Mon Oct 6 17:55:14 2008 New Revision: 58674 Modified: pypy/branch/oo-jit/pypy/translator/cli/dotnet.py pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs pypy/branch/oo-jit/pypy/translator/cli/test/test_dotnet.py Log: implement two helpers to convert between ootype.Class and System.Type and viceversa Modified: pypy/branch/oo-jit/pypy/translator/cli/dotnet.py ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/dotnet.py (original) +++ pypy/branch/oo-jit/pypy/translator/cli/dotnet.py Mon Oct 6 17:55:14 2008 @@ -723,3 +723,16 @@ } known_delegates_class = {} + +cVoid = classof(CLR.System.Void) +def class2type(cls): + 'Cast a PBC of type ootype.Class into a System.Type instance' + if cls is cVoid: + return None + return clidowncast(box(cls), CLR.System.Type) + +def type2class(clitype): + 'Cast a System.Type instance to a PBC of type ootype.Class' +## if clitype is None: +## return cVoid + return unbox(clitype, ootype.Class) Modified: pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Mon Oct 6 17:55:14 2008 @@ -283,6 +283,9 @@ public static string OOString(object obj, int base_) { + if (obj == null) + return ""; + else return string.Format("<{0} object>", obj.GetType().FullName); } Modified: pypy/branch/oo-jit/pypy/translator/cli/test/test_dotnet.py ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/test/test_dotnet.py (original) +++ pypy/branch/oo-jit/pypy/translator/cli/test/test_dotnet.py Mon Oct 6 17:55:14 2008 @@ -8,7 +8,8 @@ from pypy.translator.cli.dotnet import SomeCliClass, SomeCliStaticMethod,\ NativeInstance, CLR, box, unbox, OverloadingResolver, NativeException,\ native_exc, new_array, init_array, typeof, eventhandler, clidowncast,\ - cliupcast, classof, cast_to_native_object, cast_from_native_object + cliupcast, classof, cast_to_native_object, cast_from_native_object,\ + class2type, type2class System = CLR.System ArrayList = CLR.System.Collections.ArrayList @@ -483,6 +484,31 @@ res = self.interpret(fn, [True]) assert res == 42 + def test_class2type(self): + cInt32 = classof(System.Int32) + cString = classof(System.String) + def fn(flag): + if flag: + cls = cInt32 + else: + cls = cString + clitype = class2type(cls) + return clitype.get_FullName() + res = self.interpret(fn, [True]) + assert res == 'System.Int32' + + def test_type2class(self): + cInt32 = classof(System.Int32) + def fn(flag): + if flag: + clitype = typeof(System.Int32) + else: + clitype = typeof(System.String) + cls = type2class(clitype) + return cls is cInt32 + res = self.interpret(fn, [True]) + assert res + def test_instance_wrapping(self): class Foo: pass @@ -695,3 +721,6 @@ def test_cast_native_object(self): pass # it works only when translated + + def test_type2class(self): + pass # it works only when translated From arigo at codespeak.net Mon Oct 6 17:56:51 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 17:56:51 +0200 (CEST) Subject: [pypy-svn] r58675 - in pypy/branch/2.5-merge/pypy: interpreter lib module/__builtin__ module/__pypy__ module/sys Message-ID: <20081006155651.CCD62169F95@codespeak.net> Author: arigo Date: Mon Oct 6 17:56:50 2008 New Revision: 58675 Modified: pypy/branch/2.5-merge/pypy/interpreter/pycode.py pypy/branch/2.5-merge/pypy/lib/imp.py pypy/branch/2.5-merge/pypy/module/__builtin__/importing.py pypy/branch/2.5-merge/pypy/module/__pypy__/__init__.py pypy/branch/2.5-merge/pypy/module/sys/__init__.py pypy/branch/2.5-merge/pypy/module/sys/version.py Log: (iko, arigo) Change -again- the way the magic numbers are stored in the pyc files. This has the result that imp.get_magic() on top of a pypy-c returns a number that is within the same range as CPython's. This is necessary to make PyPy-on-pypy-c work correctly :-/ Modified: pypy/branch/2.5-merge/pypy/interpreter/pycode.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/pycode.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/pycode.py Mon Oct 6 17:56:50 2008 @@ -26,6 +26,12 @@ CO_NESTED = 0x0010 CO_GENERATOR = 0x0020 +# Magic numbers for the bytecode version in code objects. +# See comments in pypy/module/__builtin__/importing. +cpython_magic, = struct.unpack(" Author: antocuni Date: Mon Oct 6 18:01:07 2008 New Revision: 58676 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Log: implement replay; test_known_nonzero mostly pass, but with some args it loops because of some problem probably related to promotion Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py Mon Oct 6 18:01:07 2008 @@ -46,6 +46,9 @@ return self.clitype def register_types(self, types): + if not self.is_open(): + return # XXX + assert self.is_open() newcounter = {} for clitype in types: Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Mon Oct 6 18:01:07 2008 @@ -6,11 +6,13 @@ from pypy.jit.codegen.model import AbstractRGenOp, GenBuilder, GenLabel from pypy.jit.codegen.model import GenVarOrConst, GenVar, GenConst from pypy.jit.codegen.model import CodeGenSwitch +from pypy.jit.codegen.model import ReplayBuilder, dummy_var from pypy.jit.codegen.cli import operation as ops from pypy.jit.codegen.cli.methodfactory import get_method_wrapper from pypy.jit.codegen.cli.args_manager import ArgsManager from pypy.translator.cli.dotnet import CLR, typeof, new_array, init_array from pypy.translator.cli.dotnet import box, unbox, clidowncast, classof +from pypy.translator.cli.dotnet import class2type, type2class from pypy.translator.cli import dotnet System = CLR.System DelegateHolder = CLR.pypy.runtime.DelegateHolder @@ -114,19 +116,15 @@ def getCliType(self): return class2type(self.ooclass) -def class2type(cls): - 'Cast a PBC of type ootype.Class into a System.Type instance' - if cls is cVoid: - return None - else: - return clidowncast(box(cls), System.Type) - class __extend__(GenVarOrConst): __metaclass__ = extendabletype def getCliType(self): raise NotImplementedError - + + def getkind(self): + return type2class(self.getCliType()) + def load(self, builder): raise NotImplementedError @@ -426,8 +424,7 @@ return builder, graph.gv_entrypoint, graph.inputargs_gv[:] def replay(self, label): - print 'Replay!' - raise NotImplementedError + return ReplayBuilder(self), [dummy_var] * len(label.inputargs_gv) class GraphInfo: Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Mon Oct 6 18:01:07 2008 @@ -89,7 +89,7 @@ check_count_depth = False # see test_self_referential_structures def test_known_nonzero(self): - py.test.skip("replay: NotImplementedError") + py.test.skip("something wrong with promotion") def test_debug_assert_ptr_nonzero(self): py.test.skip("replay: NotImplementedError") From antocuni at codespeak.net Mon Oct 6 18:06:22 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 6 Oct 2008 18:06:22 +0200 (CEST) Subject: [pypy-svn] r58677 - pypy/branch/oo-jit/pypy/jit/codegen/cli/test Message-ID: <20081006160622.D1812169FEB@codespeak.net> Author: antocuni Date: Mon Oct 6 18:06:21 2008 New Revision: 58677 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Log: also this tests loops for the same reason as test_knonw_nonzero Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Mon Oct 6 18:06:21 2008 @@ -92,7 +92,7 @@ py.test.skip("something wrong with promotion") def test_debug_assert_ptr_nonzero(self): - py.test.skip("replay: NotImplementedError") + py.test.skip("something wrong with promotion") def test_indirect_red_call_with_exc(self): py.test.skip("replay: NotImplementedError") From antocuni at codespeak.net Mon Oct 6 18:09:24 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 6 Oct 2008 18:09:24 +0200 (CEST) Subject: [pypy-svn] r58679 - pypy/branch/oo-jit/pypy/jit/codegen/cli/test Message-ID: <20081006160924.7ED50169F33@codespeak.net> Author: antocuni Date: Mon Oct 6 18:09:24 2008 New Revision: 58679 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Log: umphf, two more tests failing for the same reason. Time to investigate more Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Mon Oct 6 18:09:24 2008 @@ -101,10 +101,10 @@ py.test.skip("TODO: exceptions") def test_learn_nonzeroness(self): - py.test.skip("replay: NotImplementedError") + py.test.skip("something wrong with promotion") def test_freeze_booleffects_correctly(self): - py.test.skip("replay: NotImplementedError") + py.test.skip("something wrong with promotion") def test_degenerated_at_return(self): py.test.skip('test framework does not support getattr on returned instances') From cfbolz at codespeak.net Mon Oct 6 18:37:19 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 6 Oct 2008 18:37:19 +0200 (CEST) Subject: [pypy-svn] r58680 - in pypy/dist/pypy/translator/tool: . test Message-ID: <20081006163719.120AF16A204@codespeak.net> Author: cfbolz Date: Mon Oct 6 18:37:18 2008 New Revision: 58680 Modified: pypy/dist/pypy/translator/tool/staticsizereport.py pypy/dist/pypy/translator/tool/test/test_staticsizereport.py Log: fix some corner cases Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Mon Oct 6 18:37:18 2008 @@ -12,23 +12,31 @@ if arrayfld: length = len(getattr(ptr, arrayfld)) else: - length = len(ptr) - return convert_offset_to_int(llmemory.sizeof(TYPE, length)) - return convert_offset_to_int(llmemory.sizeof(TYPE)) + try: + length = len(ptr) + except TypeError: + print "couldn't find size of", ptr + return 0 + else: + length = None + return convert_offset_to_int(llmemory.sizeof(TYPE, length)) -def group_static_size_by_lltype(database): +def by_lltype(obj): + return typeOf(obj) + +def group_static_size(database, grouper=by_lltype): totalsize = {} numobjects = {} for node in database.globalcontainers(): obj = node.obj - group = typeOf(obj) + group = grouper(obj) totalsize[group] = totalsize.get(group, 0) + guess_size(obj) numobjects[group] = numobjects.get(group, 0) + 1 return totalsize, numobjects -def print_static_size_by_lltype(database): - totalsize, numobjects = group_static_size_by_lltype(database) +def print_static_size(database, grouper=by_lltype): + totalsize, numobjects = group_static_size(database, grouper) l = [(size, key) for key, size in totalsize.iteritems()] l.sort() l.reverse() Modified: pypy/dist/pypy/translator/tool/test/test_staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/test/test_staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/test/test_staticsizereport.py Mon Oct 6 18:37:18 2008 @@ -1,5 +1,5 @@ from pypy.translator.c.test.test_typed import CompilationTestCase -from pypy.translator.tool.staticsizereport import group_static_size_by_lltype +from pypy.translator.tool.staticsizereport import group_static_size class TestStaticSizeReport(CompilationTestCase): def test_simple(self): @@ -16,7 +16,7 @@ return a.key return a.next.key func = self.getcompiled(f, [int]) - size, num = group_static_size_by_lltype(self.builder.db) + size, num = group_static_size(self.builder.db) for key, value in num.iteritems(): if "staticsizereport.A" in str(key) and "vtable" not in str(key): assert value == 101 From arigo at codespeak.net Mon Oct 6 18:51:17 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 18:51:17 +0200 (CEST) Subject: [pypy-svn] r58681 - pypy/branch/2.5-merge/lib-python/modified-2.5.1/test Message-ID: <20081006165117.85E8B16A15D@codespeak.net> Author: arigo Date: Mon Oct 6 18:51:16 2008 New Revision: 58681 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py Log: (iko, arigo) Another "why??". Well, it's the same one really. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py Mon Oct 6 18:51:16 2008 @@ -392,12 +392,13 @@ self.assert_(a is c) # test tee_new - t1, t2 = tee('abc') - tnew = type(t1) - self.assertRaises(TypeError, tnew) - self.assertRaises(TypeError, tnew, 10) - t3 = tnew(t1) - self.assert_(list(t1) == list(t2) == list(t3) == list('abc')) + # XXX the same "why??" as above + #t1, t2 = tee('abc') + #tnew = type(t1) + #self.assertRaises(TypeError, tnew) + #self.assertRaises(TypeError, tnew, 10) + #t3 = tnew(t1) + #self.assert_(list(t1) == list(t2) == list(t3) == list('abc')) # test that tee objects are weak referencable a, b = tee(xrange(10)) From xoraxax at codespeak.net Mon Oct 6 18:56:40 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 6 Oct 2008 18:56:40 +0200 (CEST) Subject: [pypy-svn] r58682 - pypy/dist/pypy/rpython/memory Message-ID: <20081006165640.5061216A16D@codespeak.net> Author: xoraxax Date: Mon Oct 6 18:56:39 2008 New Revision: 58682 Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py Log: Use rffis sizeof a second time as well in lltypelayout. Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypelayout.py (original) +++ pypy/dist/pypy/rpython/memory/lltypelayout.py Mon Oct 6 18:56:39 2008 @@ -51,7 +51,11 @@ if isinstance(TYPE, lltype.Primitive): if TYPE == lltype.Void: return 0 - return struct.calcsize(primitive_to_fmt[TYPE]) + try: + return struct.calcsize(primitive_to_fmt[TYPE]) + except KeyError: + from pypy.rpython.lltypesystem import rffi + return rffi.sizeof(TYPE) elif isinstance(TYPE, lltype.Ptr): return struct.calcsize("P") elif isinstance(TYPE, lltype.Struct): From arigo at codespeak.net Mon Oct 6 18:59:07 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 18:59:07 +0200 (CEST) Subject: [pypy-svn] r58683 - in pypy/branch/2.5-merge/pypy/module/itertools: . test Message-ID: <20081006165907.8C941169F15@codespeak.net> Author: arigo Date: Mon Oct 6 18:59:06 2008 New Revision: 58683 Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Log: (iko, arigo) Make itertools.tee() results weakrefable. Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py Mon Oct 6 18:59:06 2008 @@ -1,6 +1,6 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root from pypy.rlib.rarithmetic import ovfcheck @@ -726,7 +726,9 @@ W_TeeIterable.typedef = TypeDef( '_tee', __iter__ = interp2app(W_TeeIterable.iter_w, unwrap_spec=['self']), - next = interp2app(W_TeeIterable.next_w, unwrap_spec=['self'])) + next = interp2app(W_TeeIterable.next_w, unwrap_spec=['self']), + __weakref__ = make_weakref_descr(W_TeeIterable), + ) W_TeeIterable.typedef.acceptable_as_base_class = False Modified: pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Mon Oct 6 18:59:06 2008 @@ -604,3 +604,10 @@ ] for method in methods: assert method.__doc__ + + def test_tee_weakrefable(self): + import itertools, weakref + + a, b = itertools.tee(iter('abc')) + ref = weakref.ref(b) + assert ref() is b From fijal at codespeak.net Mon Oct 6 19:01:36 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 6 Oct 2008 19:01:36 +0200 (CEST) Subject: [pypy-svn] r58684 - pypy/branch/gc-experiments/pypy/rpython Message-ID: <20081006170136.85060169F35@codespeak.net> Author: fijal Date: Mon Oct 6 19:01:34 2008 New Revision: 58684 Modified: pypy/branch/gc-experiments/pypy/rpython/llinterp.py Log: op_raw_memmove implementation for llinterp Modified: pypy/branch/gc-experiments/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/llinterp.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/llinterp.py Mon Oct 6 19:01:34 2008 @@ -895,6 +895,8 @@ checkadr(toaddr) llmemory.raw_memcopy(fromaddr, toaddr, size) + op_raw_memmove = op_raw_memcopy # this is essentially the same here + def op_raw_load(self, addr, typ, offset): checkadr(addr) value = getattr(addr, str(typ).lower())[offset] From fijal at codespeak.net Mon Oct 6 19:01:53 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 6 Oct 2008 19:01:53 +0200 (CEST) Subject: [pypy-svn] r58685 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081006170153.32654169F1F@codespeak.net> Author: fijal Date: Mon Oct 6 19:01:50 2008 New Revision: 58685 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Support for clearing memory after we're done Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Mon Oct 6 19:01:50 2008 @@ -47,6 +47,8 @@ FREE_SPACE_MULTIPLIER = 3 FREE_SPACE_DIVIDER = 2 FREE_SPACE_ADD = 256 +# XXX adjust +GC_CLEARANCE = 32*1024 class MarkCompactGC(MovingGCBase): HDR = lltype.Struct('header', ('tid', lltype.Signed), @@ -309,6 +311,8 @@ def compact(self, resizing): fromaddr = self.space size_gc_header = self.gcheaderbuilder.size_gc_header + start = fromaddr + end = fromaddr while fromaddr < self.free: hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) obj = fromaddr + size_gc_header @@ -320,10 +324,26 @@ else: ll_assert(self.is_forwarded(obj), "not forwarded, surviving obj") forward_ptr = hdr.forward_ptr + if resizing: + end = fromaddr hdr.forward_ptr = NULL hdr.tid &= ~(GCFLAG_MARKBIT|GCFLAG_FINALIZATION_ORDERING) - #if fromaddr != forward_ptr: - llmemory.raw_memmove(fromaddr, forward_ptr, totalsize) + if fromaddr != forward_ptr: + #llop.debug_print(lltype.Void, "Copying from to", + # fromaddr, forward_ptr, totalsize) + llmemory.raw_memmove(fromaddr, forward_ptr, totalsize) + if resizing and end - start > GC_CLEARANCE: + diff = end - start + #llop.debug_print(lltype.Void, "Cleaning", start, diff) + diff = (diff / GC_CLEARANCE) * GC_CLEARANCE + #llop.debug_print(lltype.Void, "Cleaning", start, diff) + end = start + diff + if we_are_translated(): + # XXX wuaaaaa.... those objects are freed incorrectly + # here in case of test_gc + llarena.arena_reset(start, diff, True) + start += diff + fromaddr += totalsize def debug_check_object(self, obj): From arigo at codespeak.net Mon Oct 6 19:14:00 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 6 Oct 2008 19:14:00 +0200 (CEST) Subject: [pypy-svn] r58686 - pypy/branch/2.5-merge/pypy/module/_minimal_curses Message-ID: <20081006171400.5C45216849B@codespeak.net> Author: arigo Date: Mon Oct 6 19:13:58 2008 New Revision: 58686 Modified: pypy/branch/2.5-merge/pypy/module/_minimal_curses/__init__.py pypy/branch/2.5-merge/pypy/module/_minimal_curses/interp_curses.py Log: (iko, arigo) Finish previous check-in. Modified: pypy/branch/2.5-merge/pypy/module/_minimal_curses/__init__.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_minimal_curses/__init__.py (original) +++ pypy/branch/2.5-merge/pypy/module/_minimal_curses/__init__.py Mon Oct 6 19:13:58 2008 @@ -1,9 +1,13 @@ +try: + import _curses +except ImportError: + import _minimal_curses as _curses # when running on top of pypy-c from pypy.interpreter.mixedmodule import MixedModule from pypy.module._minimal_curses import fficurses from pypy.module._minimal_curses import interp_curses from pypy.rlib.nonconst import NonConstant -import _curses + class Module(MixedModule): """ Low-level interface for curses module, @@ -21,7 +25,6 @@ 'tparm' : 'interp_curses.tparm', } -import _curses for i in dir(_curses): val = getattr(_curses, i) if i.isupper() and type(val) is int: Modified: pypy/branch/2.5-merge/pypy/module/_minimal_curses/interp_curses.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_minimal_curses/interp_curses.py (original) +++ pypy/branch/2.5-merge/pypy/module/_minimal_curses/interp_curses.py Mon Oct 6 19:13:58 2008 @@ -1,8 +1,7 @@ from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError - -import _curses +from pypy.module._minimal_curses import _curses class ModuleInfo: def __init__(self): From cfbolz at codespeak.net Tue Oct 7 10:48:30 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 7 Oct 2008 10:48:30 +0200 (CEST) Subject: [pypy-svn] r58698 - pypy/extradoc/sprintinfo/october-2008 Message-ID: <20081007084830.E34BD169EA9@codespeak.net> Author: cfbolz Date: Tue Oct 7 10:48:30 2008 New Revision: 58698 Modified: pypy/extradoc/sprintinfo/october-2008/planning.txt Log: planning for today Modified: pypy/extradoc/sprintinfo/october-2008/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/october-2008/planning.txt (original) +++ pypy/extradoc/sprintinfo/october-2008/planning.txt Tue Oct 7 10:48:30 2008 @@ -10,40 +10,49 @@ - Samuele - Iko - Armin - - Holger in theory + - Holger in practice Tasks: - - improve the 64-bit JIT backend (John, Anto) + - improve the 64-bit JIT backend PROGRESS (John, ...) - - merge the pypy-pytrunk branch (Samuele) + - merge the pypy-pytrunk branch DONE: merged and removed - - run the CPython tests through buildbot on pypy-c + - run translation and the CPython tests through buildbot on pypy-c + SOME PROGRESS (Samuele, Holger) + + - get access to bigdog's Windows machine and set up a buildbot slave - look at the TODO list of the buildbot stuff - - merge the 2.5 branch + - merge the 2.5 branch (Iko, Armin, Maciek, Jakub, Carl Friedrich) + - fix module bugs: BASICALLY DONE + - update stdlib to 2.5.2 + - run more CPython tests - windows buildbot slave - - looking at the static data of pypy-c (Carl Friedrich, Alexander) + - looking at the static data of pypy-c IN-PROGRESS (Alexander, Anto) - - use shared dicts for oldstyle classes (Carl Friedrich, Alexander) + - use shared dicts for oldstyle classes DONE - - malloc-removal-directed inlining to reduce the code size (Armin, Iko) + - malloc-removal-directed inlining to reduce the code size NEW APPROACH NEEDED - measuring memory behaviour - run memory-benchmarks nightly? + - merge gc-experiments branch? - builtin-profiling branch needs to be merged + - py-lib needs some fixes about pdb + Discussion Tasks: - JIT roadmap From pedronis at codespeak.net Tue Oct 7 11:47:29 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 7 Oct 2008 11:47:29 +0200 (CEST) Subject: [pypy-svn] r58701 - in pypy/build/bot2/pypybuildbot: . test Message-ID: <20081007094729.65C47169E6E@codespeak.net> Author: pedronis Date: Tue Oct 7 11:47:28 2008 New Revision: 58701 Added: pypy/build/bot2/pypybuildbot/test/test_steps.py (contents, props changed) Modified: pypy/build/bot2/pypybuildbot/steps.py Log: white-boxy wrt buildbot test and fix Modified: pypy/build/bot2/pypybuildbot/steps.py ============================================================================== --- pypy/build/bot2/pypybuildbot/steps.py (original) +++ pypy/build/bot2/pypybuildbot/steps.py Tue Oct 7 11:47:28 2008 @@ -43,9 +43,11 @@ def __init__(self, translationArgs, targetArgs, workdir="build/pypy/translator/goal", *a, **kw): + kw['translationArgs'] = translationArgs + kw['targetArgs'] = targetArgs + shell.ShellCommand.__init__(self, workdir, *a, **kw) self.command = (self.command + translationArgs + [self.translationTarget] + targetArgs) - shell.ShellCommand.__init__(self, workdir, *a, **kw) # ________________________________________________________________ @@ -97,7 +99,7 @@ setup_steps(platform, self) - self.addStep(Translate(translationArgs=["-O0"], targetArgs=["-no-allworkingmodules"])) + self.addStep(Translate(["-O0"], ["-no-allworkingmodules"])) self.addStep(shell.ShellCommand( description="lib-python test", Added: pypy/build/bot2/pypybuildbot/test/test_steps.py ============================================================================== --- (empty file) +++ pypy/build/bot2/pypybuildbot/test/test_steps.py Tue Oct 7 11:47:28 2008 @@ -0,0 +1,15 @@ +from pypybuildbot import steps + + +def test_Translate(): + expected = ['translate.py', '--batch', '-O0', + 'targetpypystandalone', '--no-allworkingmodules'] + + translateInst = steps.Translate(['-O0'], ['--no-allworkingmodules']) + + assert translateInst.command[-len(expected):] == expected + + translateFactory, kw = translateInst.factory + rebuiltTranslate = translateFactory(**kw) + + assert rebuiltTranslate.command[-len(expected):] == expected From arigo at codespeak.net Tue Oct 7 11:49:56 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 11:49:56 +0200 (CEST) Subject: [pypy-svn] r58702 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081007094956.96CEC169EA3@codespeak.net> Author: arigo Date: Tue Oct 7 11:49:56 2008 New Revision: 58702 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: (iko, arigo) "Out-of-progress". Should try another approach... Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Tue Oct 7 11:49:56 2008 @@ -115,6 +115,7 @@ self.names_and_types = [] self.name2index = {} self.initialize_type(MALLOCTYPE) + self.immutable_struct = MALLOCTYPE._hints.get('immutable') self.pending_specializations = [] self.cache = BlockSpecCache(fallback=mallocv.cache) @@ -215,7 +216,10 @@ def expand_vars(self, vars): result_v = [] for v in vars: - result_v += self.renamings[v] + if isinstance(v, Variable): + result_v += self.renamings[v] + else: + result_v.append(v) return result_v def initialize_renamings(self, inputargs): @@ -274,29 +278,37 @@ fobj = op.args[0].value._obj if hasattr(fobj, 'graph'): graph = fobj.graph - nb_args = len(op.args) - 1 - assert nb_args == len(graph.getargs()) - newargs = [] - for i in range(nb_args): - v1 = op.args[1+i] - if v1 not in self.curvars: - newargs.append(v1) - else: - inputarg_index_in_specgraph = len(newargs) - v2 = graph.getargs()[inputarg_index_in_specgraph] - assert v1.concretetype == v2.concretetype - specgraph = self.mallocspec.get_specialized_graph(graph, - v2) - newargs.extend(self.expanded_v) - graph = specgraph - assert len(newargs) == len(graph.getargs()) - fspecptr = getfunctionptr(graph) - newargs.insert(0, Constant(fspecptr, - concretetype=lltype.typeOf(fspecptr))) - newresult = Variable(op.result) - newresult.concretetype = op.result.concretetype - self.renamings[op.result] = [newresult] - newop = SpaceOperation('direct_call', newargs, newresult) - return [newop] + if self.mallocspec.immutable_struct: + return self.handle_call_with_immutable(op, graph) + else: + return self.handle_call_with_mutable(op, graph) else: return self.handle_default(op) + + def handle_call_with_immutable(self, op, graph): + nb_args = len(op.args) - 1 + assert nb_args == len(graph.getargs()) + newargs = [] + for i in range(nb_args): + v1 = op.args[1+i] + if v1 not in self.curvars: + newargs.append(v1) + else: + inputarg_index_in_specgraph = len(newargs) + v2 = graph.getargs()[inputarg_index_in_specgraph] + assert v1.concretetype == v2.concretetype + specgraph = self.mallocspec.get_specialized_graph(graph, v2) + newargs.extend(self.expanded_v) + graph = specgraph + assert len(newargs) == len(graph.getargs()) + fspecptr = getfunctionptr(graph) + newargs.insert(0, Constant(fspecptr, + concretetype=lltype.typeOf(fspecptr))) + newresult = Variable(op.result) + newresult.concretetype = op.result.concretetype + self.renamings[op.result] = [newresult] + newop = SpaceOperation('direct_call', newargs, newresult) + return [newop] + + def handle_call_with_mutable(self, op, graph): + return self.handle_default(op) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Tue Oct 7 11:49:56 2008 @@ -80,6 +80,20 @@ return g((x+1, x-1)) graph = self.check(f, [int], [10], 99) + def test_direct_call_mutable_simple(self): + py.test.skip("later") + A = lltype.GcStruct('A', ('x', lltype.Signed)) + def g(a): + a.x += 1 + def f(x): + a = lltype.malloc(A) + a.x = x + g(a) + return a.x + graph = self.check(f, [int], [41], 42) + insns = summary(graph) + assert insns.get('direct_call', 0) == 0 # no more call, inlined + def test_fn2(self): py.test.skip("redo me") class T: From arigo at codespeak.net Tue Oct 7 11:50:37 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 11:50:37 +0200 (CEST) Subject: [pypy-svn] r58703 - pypy/dist/pypy/config Message-ID: <20081007095037.2096C169EC6@codespeak.net> Author: arigo Date: Tue Oct 7 11:50:36 2008 New Revision: 58703 Modified: pypy/dist/pypy/config/translationoption.py Log: Make listcompr off by default again. Turn it on for translate.py in all opt levels except -O0. Fixes many oo tests. Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Tue Oct 7 11:50:36 2008 @@ -146,7 +146,7 @@ "When true, look for and special-case the sequence of " "operations that results from a list comprehension and " "attempt to pre-allocate the list", - default=True, + default=False, cmdline='--listcompr'), IntOption("withsmallfuncsets", "Represent groups of less funtions than this as indices into an array", @@ -327,7 +327,6 @@ for word in words: if word == 'nobackendopt': config.translation.backendopt.suggest(none=True) - config.translation.suggest(list_comprehension_operations=False) elif word == 'lowinline': config.translation.backendopt.suggest(inline_threshold= DEFL_LOW_INLINE_THRESHOLD) @@ -338,6 +337,9 @@ else: raise ValueError(word) + hasbackendopts = 'nobackendopt' not in words + config.translation.suggest(list_comprehension_operations=hasbackendopts) + # ---------------------------------------------------------------- PLATFORMS = [ From pedronis at codespeak.net Tue Oct 7 11:53:49 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 7 Oct 2008 11:53:49 +0200 (CEST) Subject: [pypy-svn] r58704 - in pypy/build/bot2/pypybuildbot: . test Message-ID: <20081007095349.20C091684FA@codespeak.net> Author: pedronis Date: Tue Oct 7 11:53:48 2008 New Revision: 58704 Added: pypy/build/bot2/pypybuildbot/builds.py - copied unchanged from r58701, pypy/build/bot2/pypybuildbot/steps.py pypy/build/bot2/pypybuildbot/test/test_builds.py - copied, changed from r58701, pypy/build/bot2/pypybuildbot/test/test_steps.py Removed: pypy/build/bot2/pypybuildbot/steps.py pypy/build/bot2/pypybuildbot/test/test_steps.py Modified: pypy/build/bot2/pypybuildbot/master.py Log: better naming Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Tue Oct 7 11:53:48 2008 @@ -20,12 +20,12 @@ status.putChild('summary', summary.Summary()) -pypysteps = load('pypybuildbot.steps') +pypybuilds = load('pypybuildbot.builds') -pypyOwnTestFactory = pypysteps.PyPyOwnTestFactory() -pypyOwnTestFactoryWin = pypysteps.PyPyOwnTestFactory(platform="win32") +pypyOwnTestFactory = pypybuilds.PyPyOwnTestFactory() +pypyOwnTestFactoryWin = pypybuilds.PyPyOwnTestFactory(platform="win32") -pypyTranslatedLibPythonTestFactory = pypysteps.PyPyTranslaledLibPythonTestFactory() +pypyTranslatedLibPythonTestFactory = pypybuilds.PyPyTranslaledLibPythonTestFactory() BuildmasterConfig = { 'slavePortnum': slavePortnum, Copied: pypy/build/bot2/pypybuildbot/test/test_builds.py (from r58701, pypy/build/bot2/pypybuildbot/test/test_steps.py) ============================================================================== --- pypy/build/bot2/pypybuildbot/test/test_steps.py (original) +++ pypy/build/bot2/pypybuildbot/test/test_builds.py Tue Oct 7 11:53:48 2008 @@ -1,11 +1,11 @@ -from pypybuildbot import steps +from pypybuildbot import builds def test_Translate(): expected = ['translate.py', '--batch', '-O0', 'targetpypystandalone', '--no-allworkingmodules'] - translateInst = steps.Translate(['-O0'], ['--no-allworkingmodules']) + translateInst = builds.Translate(['-O0'], ['--no-allworkingmodules']) assert translateInst.command[-len(expected):] == expected From iko at codespeak.net Tue Oct 7 11:54:22 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Tue, 7 Oct 2008 11:54:22 +0200 (CEST) Subject: [pypy-svn] r58705 - pypy/branch/2.5-merge/lib-python/modified-2.5.1/test Message-ID: <20081007095422.5A813169E37@codespeak.net> Author: iko Date: Tue Oct 7 11:54:21 2008 New Revision: 58705 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_format.py Log: (iko, cfbolz) since float formatting is no longer written in python, this change is no longer needed. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_format.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_format.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_format.py Tue Oct 7 11:54:21 2008 @@ -53,8 +53,7 @@ testboth("%#.*g", (110, -1.e+100/3.)) # test some ridiculously large precision, expect overflow -#Too slow on PyPy -#testboth('%12.*f', (123456, 1.0)) +testboth('%12.*f', (123456, 1.0)) # Formatting of long integers. Overflow is not ok overflowok = 0 From hpk at codespeak.net Tue Oct 7 11:58:51 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 7 Oct 2008 11:58:51 +0200 (CEST) Subject: [pypy-svn] r58707 - in pypy/branch/2.5-merge: . lib-python pypy pypy/doc pypy/interpreter/test pypy/tool pypy/tool/pytest pypy/tool/test Message-ID: <20081007095851.B3234169E9A@codespeak.net> Author: hpk Date: Tue Oct 7 11:58:50 2008 New Revision: 58707 Added: pypy/branch/2.5-merge/pypy/testrunner_cfg.py - copied unchanged from r58623, pypy/dist/pypy/testrunner_cfg.py Modified: pypy/branch/2.5-merge/ (props changed) pypy/branch/2.5-merge/lib-python/conftest.py pypy/branch/2.5-merge/pypy/conftest.py pypy/branch/2.5-merge/pypy/doc/configuration.txt pypy/branch/2.5-merge/pypy/doc/conftest.py pypy/branch/2.5-merge/pypy/doc/getting-started.txt pypy/branch/2.5-merge/pypy/interpreter/test/test_appinterp.py pypy/branch/2.5-merge/pypy/interpreter/test/test_code.py pypy/branch/2.5-merge/pypy/tool/ansi_mandelbrot.py pypy/branch/2.5-merge/pypy/tool/ansi_print.py pypy/branch/2.5-merge/pypy/tool/pytest/appsupport.py pypy/branch/2.5-merge/pypy/tool/pytest/pypy_test_failure_demo.py pypy/branch/2.5-merge/pypy/tool/test/test_conftest1.py pypy/branch/2.5-merge/pypy/tool/test/test_pytestsupport.py Log: merge the pypy-pytrunk merge and a few subsequent fixes from pypy/dist. Modified: pypy/branch/2.5-merge/lib-python/conftest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/conftest.py (original) +++ pypy/branch/2.5-merge/lib-python/conftest.py Tue Oct 7 11:58:50 2008 @@ -20,9 +20,6 @@ from pypy.tool.pytest import appsupport from pypy.tool.pytest.confpath import pypydir, libpythondir, \ regrtestdir, modregrtestdir, testresultdir -from pypy.tool.pytest.result import Result, ResultFromMime - -pypyexecpath = pypydir.join('bin', 'pypy-c') dist_rsync_roots = ['.', '../pypy', '../py'] @@ -30,32 +27,15 @@ # Interfacing/Integrating with py.test's collection process # -# XXX no nice way to implement a --listpassing py.test option?! -#option = py.test.addoptions("compliance testing options", -# py.test.Option('-L', '--listpassing', action="store", default=None, -# type="string", dest="listpassing", -# help="just display the list of expected-to-pass tests.") - Option = py.test.config.Option option = py.test.config.addoptions("compliance testing options", - Option('-C', '--compiled', action="store_true", - default=False, dest="use_compiled", - help="use a compiled version of pypy"), - Option('--compiled-pypy', action="store", type="string", dest="pypy_executable", - default=str(pypyexecpath), - help="to use together with -C to specify the path to the " - "compiled version of pypy, by default expected in pypy/bin/pypy-c"), - Option('-E', '--extracttests', action="store_true", - default=False, dest="extracttests", - help="try to extract single tests and run them via py.test/PyPy"), Option('-T', '--timeout', action="store", type="string", default="100mp", dest="timeout", help="fail a test module after the given timeout. " "specify in seconds or 'NUMmp' aka Mega-Pystones"), - Option('--resultdir', action="store", type="string", - default=None, dest="resultdir", - help="directory under which to store results in USER at HOST subdirs", - ), + Option('--pypy', action="store", type="string", + dest="pypy", help="use given pypy executable to run lib-python tests. " + "This will run the tests directly (i.e. not through py.py)") ) def gettimeout(): @@ -68,228 +48,6 @@ return seconds return float(timeout) -def callex(space, func, *args, **kwargs): - from py.__.test.outcome import Failed - try: - return func(*args, **kwargs) - except OperationError, e: - ilevelinfo = py.code.ExceptionInfo() - if e.match(space, space.w_KeyboardInterrupt): - raise KeyboardInterrupt - appexcinfo = appsupport.AppExceptionInfo(space, e) - if appexcinfo.traceback: - print "appexcinfo.traceback:" - py.std.pprint.pprint(appexcinfo.traceback) - raise Failed(excinfo=appexcinfo) - raise Failed(excinfo=ilevelinfo) - -# -# compliance modules where we invoke test_main() usually call into -# test_support.(run_suite|run_doctests) -# we intercept those calls and use the provided information -# for our collection process. This allows us to run all the -# tests one by one. -# - -app = ApplevelClass(''' - #NOT_RPYTHON - - import unittest - from test import test_support - import sys - - def getmethods(suite_or_class): - """ flatten out suites down to TestCase instances/methods. """ - if isinstance(suite_or_class, unittest.TestCase): - res = [suite_or_class] - elif isinstance(suite_or_class, unittest.TestSuite): - res = [] - for x in suite_or_class._tests: - res.extend(getmethods(x)) - elif isinstance(suite_or_class, list): - res = [] - for x in suite_or_class: - res.extend(getmethods(x)) - else: - raise TypeError, "expected TestSuite or TestClass, got %r" %(suite_or_class) - return res - - # - # exported API - # - - def intercept_test_support(): - """ intercept calls to test_support.run_doctest and run_suite. - Return doctestmodules, suites which will hold collected - items from these test_support invocations. - """ - suites = [] - doctestmodules = [] - def hack_run_doctest(module, verbose=None): - doctestmodules.append(module) - test_support.run_doctest = hack_run_doctest - - def hack_run_suite(suite, testclass=None): - suites.append(suite) - test_support.run_suite = hack_run_suite - return suites, doctestmodules - - def collect_intercepted(suites, doctestmodules): - namemethodlist = [] - for method in getmethods(suites): - name = (method.__class__.__name__ + '.' + - method._TestCase__testMethodName) - namemethodlist.append((name, method)) - doctestlist = [] - for mod in doctestmodules: - doctestlist.append((mod.__name__, mod)) - return namemethodlist, doctestlist - - def run_testcase_method(method): - result = method.defaultTestResult() - method.run(result) - if result.errors: - assert len(result.errors) - print result.errors[0][1] - if result.failures: - assert len(result.failures) - print result.failures[0][1] - if result.failures or result.errors: - return 1 - - def set_argv(filename): - sys.argv[:] = ['python', filename] -''') - -intercept_test_support = app.interphook('intercept_test_support') -collect_intercepted = app.interphook('collect_intercepted') -run_testcase_method = app.interphook('run_testcase_method') -set_argv = app.interphook('set_argv') - -def start_intercept(space): - w_suites, w_doctestmodules = space.unpacktuple(intercept_test_support(space)) - return w_suites, w_doctestmodules - -def collect_intercept(space, w_suites, w_doctestmodules): - w_result = callex(space, collect_intercepted, space, w_suites, w_doctestmodules) - w_namemethods, w_doctestlist = space.unpacktuple(w_result) - return w_namemethods, w_doctestlist - -class SimpleRunItem(py.test.collect.Item): - """ Run a module file and compare its output - to the expected output in the output/ directory. - """ - def call_capture(self, space, func, *args): - regrtest = self.parent.regrtest - oldsysout = sys.stdout - sys.stdout = capturesysout = py.std.cStringIO.StringIO() - try: - try: - res = regrtest.run_file(space) - except: - print capturesysout.getvalue() - raise - else: - return res, capturesysout.getvalue() - finally: - sys.stdout = oldsysout - - def run(self): - # XXX integrate this into InterceptedRunModule - # but we want a py.test refactoring towards - # more autonomy of colitems regarding - # their representations - regrtest = self.parent.regrtest - space = gettestobjspace(usemodules=[]) - res, output = self.call_capture(space, regrtest.run_file, space) - - outputpath = regrtest.getoutputpath() - if outputpath: - # we want to compare outputs - # regrtest itself prepends the test_name to the captured output - result = outputpath.purebasename + "\n" + output - expected = outputpath.read(mode='r') - if result != expected: - reportdiff(expected, result) - py.test.fail("output check failed: %s" % (self.fspath.basename,)) - if output: - print output, - -# -class InterceptedRunModule(py.test.collect.Module): - """ special handling for tests with a proper 'def test_main(): ' - definition invoking test_support.run_suite or run_unittest - (XXX add support for test_support.run_doctest). - """ - def __init__(self, name, parent, regrtest): - super(InterceptedRunModule, self).__init__(name, parent) - self.regrtest = regrtest - self.fspath = regrtest.getfspath() - - def _prepare(self): - if hasattr(self, 'name2item'): - return - self.name2item = {} - space = gettestobjspace(usemodules=self.regrtest.usemodules) - if self.regrtest.dumbtest or self.regrtest.getoutputpath(): - self.name2item['output'] = SimpleRunItem('output', self) - return - - tup = start_intercept(space) - self.regrtest.run_file(space) - w_namemethods, w_doctestlist = collect_intercept(space, *tup) - - # setup {name -> wrapped testcase method} - for w_item in space.unpackiterable(w_namemethods): - w_name, w_method = space.unpacktuple(w_item) - name = space.str_w(w_name) - testitem = AppTestCaseMethod(name, parent=self, w_method=w_method) - self.name2item[name] = testitem - - # setup {name -> wrapped doctest module} - for w_item in space.unpackiterable(w_doctestlist): - w_name, w_module = space.unpacktuple(w_item) - name = space.str_w(w_name) - testitem = AppDocTestModule(name, parent=self, w_module=w_module) - self.name2item[name] = testitem - - def run(self): - self._prepare() - keys = self.name2item.keys() - keys.sort(lambda x,y: cmp(x.lower(), y.lower())) - return keys - - def join(self, name): - self._prepare() - try: - return self.name2item[name] - except KeyError: - pass - -class AppDocTestModule(py.test.collect.Item): - def __init__(self, name, parent, w_module): - super(AppDocTestModule, self).__init__(name, parent) - self.w_module = w_module - - def run(self): - py.test.skip("application level doctest modules not supported yet.") - -class AppTestCaseMethod(py.test.collect.Item): - def __init__(self, name, parent, w_method): - super(AppTestCaseMethod, self).__init__(name, parent) - self.space = gettestobjspace() - self.w_method = w_method - - def run(self): - space = self.space - filename = str(self.fspath) - callex(space, set_argv, space, space.wrap(filename)) - #space.call_function(self.w_method) - w_res = callex(space, run_testcase_method, space, self.w_method) - if space.is_true(w_res): - raise AssertionError( - "testcase instance invociation raised errors, see stdoudt") - # ________________________________________________________________________ # # classification of all tests files (this is ongoing work) @@ -298,24 +56,16 @@ class RegrTest: """ Regression Test Declaration.""" def __init__(self, basename, enabled=False, dumbtest=False, - oldstyle=False, core=False, + core=False, compiler=None, usemodules = ''): self.basename = basename self.enabled = enabled self.dumbtest = dumbtest - # we have to determine the value of oldstyle - # lazily because at RegrTest() call time the command - # line options haven't been parsed! - self._oldstyle = oldstyle self._usemodules = usemodules.split() self._compiler = compiler self.core = core - def oldstyle(self): - return self._oldstyle #or pypy_option.oldstyle - oldstyle = property(oldstyle) - def usemodules(self): return self._usemodules #+ pypy_option.usemodules usemodules = property(usemodules) @@ -326,7 +76,7 @@ def getoptions(self): l = [] - for name in 'oldstyle', 'core': + for name in ['core']: if getattr(self, name): l.append(name) for name in self.usemodules: @@ -366,18 +116,13 @@ self._prepare(space) fspath = self.getfspath() assert fspath.check() - if self.oldstyle: - space.enable_old_style_classes_as_default_metaclass() - try: - modname = fspath.purebasename - space.appexec([], '''(): - from test import %(modname)s - m = %(modname)s - if hasattr(m, 'test_main'): - m.test_main() - ''' % locals()) - finally: - space.enable_new_style_classes_as_default_metaclass() + modname = fspath.purebasename + space.appexec([], '''(): + from test import %(modname)s + m = %(modname)s + if hasattr(m, 'test_main'): + m.test_main() + ''' % locals()) testmap = [ RegrTest('test___all__.py', enabled=True, core=True), @@ -423,34 +168,32 @@ RegrTest('test_cgi.py', enabled=True), RegrTest('test_charmapcodec.py', enabled=True, core=True), RegrTest('test_cl.py', enabled=False, dumbtest=1), - RegrTest('test_class.py', enabled=True, oldstyle=True, core=True), + RegrTest('test_class.py', enabled=True, core=True), RegrTest('test_cmath.py', enabled=True, dumbtest=1, core=True), RegrTest('test_codeccallbacks.py', enabled=True, core=True), - RegrTest('test_coding.py', enabled=True), - RegrTest('test_codecencodings_cn.py', enabled=True), - RegrTest('test_codecencodings_hk.py', enabled=True), - RegrTest('test_codecencodings_jp.py', enabled=True), - RegrTest('test_codecencodings_kr.py', enabled=True), - RegrTest('test_codecencodings_tw.py', enabled=True), - - RegrTest('test_codecmaps_cn.py', enabled=True), - RegrTest('test_codecmaps_hk.py', enabled=True), - RegrTest('test_codecmaps_jp.py', enabled=True), - RegrTest('test_codecmaps_kr.py', enabled=True), - RegrTest('test_codecmaps_tw.py', enabled=True), + RegrTest('test_codecencodings_cn.py', enabled=False), + RegrTest('test_codecencodings_hk.py', enabled=False), + RegrTest('test_codecencodings_jp.py', enabled=False), + RegrTest('test_codecencodings_kr.py', enabled=False), + RegrTest('test_codecencodings_tw.py', enabled=False), + + RegrTest('test_codecmaps_cn.py', enabled=False), + RegrTest('test_codecmaps_hk.py', enabled=False), + RegrTest('test_codecmaps_jp.py', enabled=False), + RegrTest('test_codecmaps_kr.py', enabled=False), + RegrTest('test_codecmaps_tw.py', enabled=False), RegrTest('test_codecs.py', enabled=True, core=True), RegrTest('test_codeop.py', enabled=True, core=True), - RegrTest('test_coercion.py', enabled=True, oldstyle=True, core=True), + RegrTest('test_coercion.py', enabled=True, core=True), RegrTest('test_colorsys.py', enabled=True), RegrTest('test_commands.py', enabled=True), - RegrTest('test_compare.py', enabled=True, oldstyle=True, core=True), + RegrTest('test_compare.py', enabled=True, core=True), RegrTest('test_compile.py', enabled=True, core=True), RegrTest('test_compiler.py', enabled=True, core=False), # this test tests the compiler package from stdlib RegrTest('test_complex.py', enabled=True, core=True), RegrTest('test_contains.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_contextlib.py', enabled=True, core=True), RegrTest('test_cookie.py', enabled=False), RegrTest('test_cookielib.py', enabled=False), RegrTest('test_copy.py', enabled=True, core=True), @@ -465,10 +208,9 @@ RegrTest('test_dbm.py', enabled=False, dumbtest=1), RegrTest('test_decimal.py', enabled=True), RegrTest('test_decorators.py', enabled=True, core=True), - RegrTest('test_defaultdict.py', enabled=True), RegrTest('test_deque.py', enabled=True, core=True), - RegrTest('test_descr.py', enabled=True, core=True, oldstyle=True, usemodules='_weakref'), - RegrTest('test_descrtut.py', enabled=True, core=True, oldstyle=True), + RegrTest('test_descr.py', enabled=True, core=True, usemodules='_weakref'), + RegrTest('test_descrtut.py', enabled=True, core=True), RegrTest('test_dict.py', enabled=True, core=True), RegrTest('test_difflib.py', enabled=True, dumbtest=1), @@ -520,13 +262,16 @@ RegrTest('test_gl.py', enabled=False, dumbtest=1), RegrTest('test_glob.py', enabled=True, core=True), - RegrTest('test_global.py', enabled=True, core=True, compiler='ast'), + RegrTest('test_global.py', enabled=True, core=True), RegrTest('test_grammar.py', enabled=True, core=True), RegrTest('test_grp.py', enabled=False), #rev 10840: ImportError: grp RegrTest('test_gzip.py', enabled=False, dumbtest=1), RegrTest('test_hash.py', enabled=True, core=True), + RegrTest('test_hashlib.py', enabled=True, core=True), + # test_hashlib comes from 2.5 + RegrTest('test_heapq.py', enabled=True, core=True), RegrTest('test_hexoct.py', enabled=True, core=True), RegrTest('test_hmac.py', enabled=True), @@ -578,7 +323,7 @@ RegrTest('test_multifile.py', enabled=True), RegrTest('test_mutants.py', enabled=True, dumbtest=1, core="possibly"), RegrTest('test_netrc.py', enabled=True), - RegrTest('test_new.py', enabled=True, core=True, oldstyle=True), + RegrTest('test_new.py', enabled=True, core=True), RegrTest('test_nis.py', enabled=False), RegrTest('test_normalization.py', enabled=False), RegrTest('test_ntpath.py', enabled=True, dumbtest=1), @@ -604,7 +349,6 @@ # seems to be the only one that invokes run_unittest # and is an unittest RegrTest('test_pep292.py', enabled=True), - RegrTest('test_pep352.py', enabled=True), RegrTest('test_pickle.py', enabled=True, core=True), RegrTest('test_pickletools.py', enabled=True, dumbtest=1, core=False), RegrTest('test_pkg.py', enabled=True, core=True), @@ -637,7 +381,7 @@ RegrTest('test_re.py', enabled=True, core=True), RegrTest('test_regex.py', enabled=False), - RegrTest('test_repr.py', enabled=True, oldstyle=True, core=True), + RegrTest('test_repr.py', enabled=True, core=True), #rev 10840: 6 of 12 tests fail. Always minor stuff like #'' != '' @@ -748,7 +492,6 @@ RegrTest('test_userlist.py', enabled=True, core=True), RegrTest('test_userstring.py', enabled=True, core=True), RegrTest('test_uu.py', enabled=False), - RegrTest('test_uuid.py', enabled=True), #rev 10840: 1 of 9 test fails RegrTest('test_warnings.py', enabled=True, core=True), @@ -758,10 +501,6 @@ RegrTest('test_whichdb.py', enabled=True), RegrTest('test_winreg.py', enabled=False), RegrTest('test_winsound.py', enabled=False), - RegrTest('test_with.py', enabled=True), - RegrTest('test_wsgiref.py', enabled=True), - RegrTest('test_xdrlib.py', enabled=True), - RegrTest('test_xml_etree.py', enabled=True), RegrTest('test_xmllib.py', enabled=False), RegrTest('test_xmlrpc.py', enabled=False), #rev 10840: 2 of 5 tests fail @@ -769,7 +508,6 @@ RegrTest('test_xpickle.py', enabled=False), RegrTest('test_xrange.py', enabled=True, core=True), RegrTest('test_zipfile.py', enabled=False, dumbtest=1), - RegrTest('test_zipfile64.py', enabled=False, dumbtest=1), RegrTest('test_zipimport.py', enabled=True, usemodules='zlib zipimport'), RegrTest('test_zlib.py', enabled=True, usemodules='zlib'), ] @@ -787,89 +525,32 @@ cache[x.basename] = x return cache.get(name, None) - def run(self): - return [x.basename for x in testmap] - - def join(self, name): - regrtest = self.get(name) - if regrtest is not None: - if not option.extracttests: - return RunFileExternal(name, parent=self, regrtest=regrtest) - else: - return InterceptedRunModule(name, self, regrtest) + def collect(self): + l = [] + for x in testmap: + name = x.basename + regrtest = self.get(name) + if regrtest is not None: + #if option.extracttests: + # l.append(InterceptedRunModule(name, self, regrtest)) + #else: + l.append(RunFileExternal(name, parent=self, regrtest=regrtest)) + return l Directory = RegrDirectory - -def getrev(path): - try: - return py.path.svnwc(pypydir).info().rev - except (KeyboardInterrupt, SystemExit): - raise - except: - # on windows people not always have 'svn' in their path - # but there are also other kinds of problems that - # could occur and we just default to revision - # "unknown" for them - return 'unknown' - -def getexecutable(_cache={}): - execpath = py.path.local(option.pypy_executable) - if not _cache: - text = execpath.sysexec('-c', - 'import sys; ' - 'print sys.version; ' - 'print sys.pypy_svn_url; ' - 'print sys.pypy_translation_info; ') - lines = [line.strip() for line in text.split('\n')] - assert len(lines) == 4 and lines[3] == '' - assert lines[2].startswith('{') and lines[2].endswith('}') - info = eval(lines[2]) - info['version'] = lines[0] - info['rev'] = eval(lines[1])[1] - _cache.update(info) - return execpath, _cache - class RunFileExternal(py.test.collect.Module): def __init__(self, name, parent, regrtest): super(RunFileExternal, self).__init__(name, parent) self.regrtest = regrtest self.fspath = regrtest.getfspath() - def tryiter(self, stopitems=()): - # shortcut pre-counting of items - return [] - - def run(self): + def collect(self): if self.regrtest.ismodified(): - return ['modified'] - return ['unmodified'] - - def join(self, name): - return ReallyRunFileExternal(name, parent=self) - - -def ensuretestresultdir(): - resultdir = option.resultdir - default_place = False - if resultdir is not None: - resultdir = py.path.local(option.resultdir) - else: - if option.use_compiled: - return None - default_place = True - resultdir = testresultdir - - if not resultdir.check(dir=1): - if default_place: - py.test.skip("""'testresult' directory not found. - To run tests in reporting mode (without -E), you first have to - check it out as follows: - svn co http://codespeak.net/svn/pypy/testresult %s""" % ( - testresultdir, )) + name = 'modified' else: - py.test.skip("'%s' test result dir not found" % resultdir) - return resultdir + name = 'unmodified' + return [ReallyRunFileExternal(name, parent=self)] # # testmethod: @@ -881,23 +562,6 @@ import getpass class ReallyRunFileExternal(py.test.collect.Item): - _resultcache = None - def _haskeyword(self, keyword): - if keyword == 'core': - return self.parent.regrtest.core - if keyword not in ('error', 'ok', 'timeout'): - return super(ReallyRunFileExternal, self).haskeyword(keyword) - if self._resultcache is None: - from pypy.tool.pytest.overview import ResultCache - self.__class__._resultcache = rc = ResultCache() - rc.parselatest() - result = self._resultcache.getlatestrelevant(self.fspath.purebasename) - if not result: return False - if keyword == 'timeout': return result.istimeout() - if keyword == 'error': return result.iserror() - if keyword == 'ok': return result.isok() - assert False, "should not be there" - def getinvocation(self, regrtest): fspath = regrtest.getfspath() python = sys.executable @@ -908,16 +572,7 @@ regr_script = pypydir.join('tool', 'pytest', 'run-script', 'regrverbose.py') - if option.use_compiled: - execpath, info = getexecutable() pypy_options = [] - if regrtest.oldstyle: - if (option.use_compiled and - not info.get('objspace.std.oldstyle', False)): - py.test.skip("old-style classes not available with this pypy-c") - pypy_options.append('--oldstyle') - if regrtest.compiler: - pypy_options.append('--compiler=%s' % regrtest.compiler) pypy_options.extend( ['--withmod-%s' % mod for mod in regrtest.usemodules]) sopt = " ".join(pypy_options) @@ -934,7 +589,12 @@ regrrun_verbosity = '0' TIMEOUT = gettimeout() - if option.use_compiled: + if option.pypy: + execpath = py.path.local(option.pypy) + if not execpath.check(): + execpath = py.path.local.sysfind(option.pypy) + if not execpath: + raise LookupError("could not find executable %r" %(option.pypy,)) cmd = "%s %s %s %s" %( execpath, regrrun, regrrun_verbosity, fspath.purebasename) @@ -949,7 +609,7 @@ regrrun, regrrun_verbosity, fspath.purebasename) return cmd - def run(self): + def runtest(self): """ invoke a subprocess running the test file via PyPy. record its output into the 'result/user at host' subdirectory. (we might want to create subdirectories for @@ -958,84 +618,37 @@ i am afraid. """ regrtest = self.parent.regrtest - result = self.getresult(regrtest) - testresultdir = ensuretestresultdir() - if testresultdir is not None: - resultdir = testresultdir.join(result['userhost']) - assert resultdir.ensure(dir=1) - - fn = resultdir.join(regrtest.basename).new(ext='.txt') - if result.istimeout(): - if fn.check(file=1): - try: - oldresult = ResultFromMime(fn) - except TypeError: - pass - else: - if not oldresult.istimeout(): - py.test.skip("timed out, not overwriting " - "more interesting non-timeout outcome") - - fn.write(result.repr_mimemessage().as_string(unixfrom=False)) - - if result['exit-status']: + exit_status, test_stdout, test_stderr = self.getresult(regrtest) + if exit_status: time.sleep(0.5) # time for a Ctrl-C to reach us :-) - print >>sys.stdout, result.getnamedtext('stdout') - print >>sys.stderr, result.getnamedtext('stderr') + print >>sys.stdout, test_stdout + print >>sys.stderr, test_stderr py.test.fail("running test failed, see stderr output below") def getstatusouterr(self, cmd): - tempdir = py.path.local.mkdtemp() - try: - stdout = tempdir.join(self.fspath.basename) + '.out' - stderr = tempdir.join(self.fspath.basename) + '.err' - if sys.platform == 'win32': - status = os.system("%s >%s 2>%s" %(cmd, stdout, stderr)) - if status>=0: - status = status - else: - status = 'abnormal termination 0x%x' % status + tempdir = py.test.ensuretemp(self.fspath.basename) + stdout = tempdir.join(self.fspath.basename) + '.out' + stderr = tempdir.join(self.fspath.basename) + '.err' + if sys.platform == 'win32': + status = os.system("%s >%s 2>%s" %(cmd, stdout, stderr)) + if status>=0: + status = status + else: + status = 'abnormal termination 0x%x' % status + else: + status = os.system("%s >>%s 2>>%s" %(cmd, stdout, stderr)) + if os.WIFEXITED(status): + status = os.WEXITSTATUS(status) else: - status = os.system("%s >>%s 2>>%s" %(cmd, stdout, stderr)) - if os.WIFEXITED(status): - status = os.WEXITSTATUS(status) - else: - status = 'abnormal termination 0x%x' % status - return status, stdout.read(mode='rU'), stderr.read(mode='rU') - finally: - tempdir.remove() + status = 'abnormal termination 0x%x' % status + return status, stdout.read(mode='rU'), stderr.read(mode='rU') def getresult(self, regrtest): cmd = self.getinvocation(regrtest) - result = Result() - fspath = regrtest.getfspath() - result['fspath'] = str(fspath) - result['pypy-revision'] = getrev(pypydir) - if option.use_compiled: - execpath, info = getexecutable() - result['pypy-revision'] = info['rev'] - result['executable'] = execpath.basename - for key, value in info.items(): - if key == 'rev': - continue - result['executable-%s' % key] = str(value) - else: - result['executable'] = 'py.py' - result['options'] = regrtest.getoptions() - result['timeout'] = gettimeout() - result['startdate'] = time.ctime() - starttime = time.time() - - # really run the test in a sub process exit_status, test_stdout, test_stderr = self.getstatusouterr(cmd) - timedout = test_stderr.rfind(26*"=" + "timedout" + 26*"=") != -1 if not timedout: timedout = test_stderr.rfind("KeyboardInterrupt") != -1 - result['execution-time'] = time.time() - starttime - result.addnamedtext('stdout', test_stdout) - result.addnamedtext('stderr', test_stderr) - outcome = 'OK' expectedpath = regrtest.getoutputpath() if not exit_status: @@ -1046,19 +659,17 @@ exit_status = 2 res, out, err = py.io.StdCapture.call(reportdiff, expected, test_stdout) outcome = 'ERROUT' - result.addnamedtext('reportdiff', out) + test_stderr += ("-" * 80 + "\n") + out else: if 'FAIL' in test_stdout or 'ERROR' in test_stderr: outcome = 'FAIL' + exit_status = 2 elif timedout: outcome = "T/O" else: outcome = "ERR" - result['exit-status'] = exit_status - result['outcome'] = outcome - return result - + return exit_status, test_stdout, test_stderr # # Sanity check (could be done more nicely too) Modified: pypy/branch/2.5-merge/pypy/conftest.py ============================================================================== --- pypy/branch/2.5-merge/pypy/conftest.py (original) +++ pypy/branch/2.5-merge/pypy/conftest.py Tue Oct 7 11:58:50 2008 @@ -29,9 +29,10 @@ help="run applevel tests directly on python interpreter (not through PyPy)"), Option('--direct', action="store_true", default=False, dest="rundirect", - help="run pexpect tests directly") + help="run pexpect tests directly"), ) + _SPACECACHE={} def gettestobjspace(name=None, **kwds): """ helper for instantiating and caching space's for testing. @@ -267,6 +268,11 @@ return space +class AppError(Exception): + + def __init__(self, excinfo): + self.excinfo = excinfo + class PyPyTestFunction(py.test.collect.Function): # All PyPy test items catch and display OperationErrors specially. # @@ -274,13 +280,18 @@ try: target(*args) except OperationError, e: + tb = sys.exc_info()[2] if e.match(space, space.w_KeyboardInterrupt): - tb = sys.exc_info()[2] raise OpErrKeyboardInterrupt, OpErrKeyboardInterrupt(), tb appexcinfo = appsupport.AppExceptionInfo(space, e) if appexcinfo.traceback: - raise Failed(excinfo=appsupport.AppExceptionInfo(space, e)) - raise + raise AppError, AppError(appexcinfo), tb + raise + + def repr_failure(self, excinfo, outerr): + if excinfo.errisinstance(AppError): + excinfo = excinfo.value.excinfo + return super(PyPyTestFunction, self).repr_failure(excinfo, outerr) _pygame_imported = False @@ -473,12 +484,11 @@ class Directory(py.test.collect.Directory): - def run(self): - # hack to exclude lib/ctypes/ - if self.fspath == rootdir.join('lib', 'ctypes', 'test'): + def consider_dir(self, path, usefilters=True): + if path == rootdir.join("lib", "ctypes", "test"): py.test.skip("These are the original ctypes tests.\n" "You can try to run them with 'pypy-c runtests.py'.") - return py.test.collect.Directory.run(self) + return super(Directory, self).consider_dir(path, usefilters=usefilters) def recfilter(self, path): # disable recursion in symlinked subdirectories Modified: pypy/branch/2.5-merge/pypy/doc/configuration.txt ============================================================================== --- pypy/branch/2.5-merge/pypy/doc/configuration.txt (original) +++ pypy/branch/2.5-merge/pypy/doc/configuration.txt Tue Oct 7 11:58:50 2008 @@ -132,6 +132,7 @@ ``OptionDescription`` instance. The attributes of the ``Config`` objects are the names of the children of the ``OptionDescription``. Example:: + >>> from pypy.config.config import OptionDescription, Config, BoolOption >>> descr = OptionDescription("options", "", [ ... BoolOption("bool", "", default=False)]) >>> Modified: pypy/branch/2.5-merge/pypy/doc/conftest.py ============================================================================== --- pypy/branch/2.5-merge/pypy/doc/conftest.py (original) +++ pypy/branch/2.5-merge/pypy/doc/conftest.py Tue Oct 7 11:58:50 2008 @@ -1,6 +1,5 @@ import py -from py.__.doc.conftest import Directory, DoctestText, ReSTChecker -from py.__.rest.directive import register_linkrole +from py.__.doc.conftest import Directory, DoctestText, DocfileTests thisdir = py.magic.autopath().dirpath() @@ -15,43 +14,34 @@ ) class PyPyDoctestText(DoctestText): - - def run(self): + def runtest(self): if not option.doctests: py.test.skip("specify --enable-doctests to run doctests") - # XXX refine doctest support with respect to scoping - return super(PyPyDoctestText, self).run() - - def execute(self, module, docstring): + super(PyPyDoctestText, self).runtest() + + def getcontent(self): # XXX execute PyPy prompts as well + # but for now just get rid of those lines l = [] - for line in docstring.split('\n'): + for line in super(PyPyDoctestText, self).getcontent().split('\n'): if line.find('>>>>') != -1: line = "" l.append(line) - text = "\n".join(l) - super(PyPyDoctestText, self).execute(module, text) - - #mod = py.std.types.ModuleType(self.fspath.basename, text) - #self.mergescopes(mod, scopes) - #failed, tot = py.std.doctest.testmod(mod, verbose=1) - #if failed: - # py.test.fail("doctest %s: %s failed out of %s" %( - # self.fspath, failed, tot)) + return "\n".join(l) -class PyPyReSTChecker(ReSTChecker): +class PyPyDocfileTests(DocfileTests): DoctestText = PyPyDoctestText class Directory(Directory): - ReSTChecker = PyPyReSTChecker - def run(self): - l = super(Directory, self).run() - if 'statistic' in l: - l.remove('statistic') - return l + DocfileTests = PyPyDocfileTests + def recfilter(self, path): + if path.basename == "statistic": + return False + return super(Directory, self).recfilter(path) try: from docutils.parsers.rst import directives, states, roles + from py.__.rest.directive import register_linkrole except ImportError: pass else: Modified: pypy/branch/2.5-merge/pypy/doc/getting-started.txt ============================================================================== --- pypy/branch/2.5-merge/pypy/doc/getting-started.txt (original) +++ pypy/branch/2.5-merge/pypy/doc/getting-started.txt Tue Oct 7 11:58:50 2008 @@ -198,6 +198,7 @@ (e.g. the object space) and any variables you have created on the PyPy prompt with the prefix ``w_``:: + .. >>> import py ; py.test.skip("skipchunk") >>>> a = 123 >>>> *** Entering interpreter-level console *** Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_appinterp.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_appinterp.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_appinterp.py Tue Oct 7 11:58:50 2008 @@ -22,7 +22,7 @@ (): y y """) - assert str(excinfo).find('y y') != -1 + assert str(excinfo.value).find('y y') != -1 def test_simple_applevel(space): app = appdef("""app(x,y): Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_code.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_code.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_code.py Tue Oct 7 11:58:50 2008 @@ -8,9 +8,14 @@ space = gettestobjspace() cls.space = space if py.test.config.option.runappdirect: - cls.w_file = space.wrap(__file__[:-1]) + filename = __file__ else: - cls.w_file = space.wrap("None<%s" % gateway.__file__[:-1]) + filename = gateway.__file__ + + if filename[-3:] != '.py': + filename = filename[:-1] + + cls.w_file = space.wrap(filename) def test_attributes(self): def f(): pass Modified: pypy/branch/2.5-merge/pypy/tool/ansi_mandelbrot.py ============================================================================== --- pypy/branch/2.5-merge/pypy/tool/ansi_mandelbrot.py (original) +++ pypy/branch/2.5-merge/pypy/tool/ansi_mandelbrot.py Tue Oct 7 11:58:50 2008 @@ -1,6 +1,6 @@ import sys -from py.__.misc.terminal_helper import ansi_print, get_terminal_width +from py.__.io.terminalwriter import ansi_print, get_terminal_width """ Black 0;30 Dark Gray 1;30 Modified: pypy/branch/2.5-merge/pypy/tool/ansi_print.py ============================================================================== --- pypy/branch/2.5-merge/pypy/tool/ansi_print.py (original) +++ pypy/branch/2.5-merge/pypy/tool/ansi_print.py Tue Oct 7 11:58:50 2008 @@ -4,7 +4,7 @@ import sys -from py.__.misc.terminal_helper import ansi_print +from py.__.io.terminalwriter import ansi_print from pypy.tool.ansi_mandelbrot import Driver class AnsiLog: Modified: pypy/branch/2.5-merge/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/branch/2.5-merge/pypy/tool/pytest/appsupport.py (original) +++ pypy/branch/2.5-merge/pypy/tool/pytest/appsupport.py Tue Oct 7 11:58:50 2008 @@ -10,8 +10,8 @@ class AppCode(object): def __init__(self, space, pycode): - self.code = space.unwrap(space.getattr(pycode, space.wrap('co_code'))) - self.raw = self.code + self.code = pycode + self.raw = pycode self.w_file = space.getattr(pycode, space.wrap('co_filename')) self.name = space.getattr(pycode, space.wrap('co_name')) self.firstlineno = space.unwrap(space.getattr(pycode, space.wrap('co_firstlineno'))) @@ -29,6 +29,9 @@ return py.code.Source(self.path.read(mode="rU")) fullsource = property(fullsource, None, None, "Full source of AppCode") + def getargs(self): + return self.raw.co_varnames[:self.raw.co_argcount] + class AppFrame(py.code.Frame): def __init__(self, space, pyframe): @@ -60,6 +63,15 @@ def is_true(self, w_value): return self.space.is_true(w_value) + def getargs(self): + space = self.space + retval = [] + for arg in self.code.getargs(): + w_val = space.getitem(self.w_locals, space.wrap(arg)) + retval.append((arg, w_val)) + return retval + + class AppExceptionInfo(py.code.ExceptionInfo): """An ExceptionInfo object representing an app-level exception.""" Modified: pypy/branch/2.5-merge/pypy/tool/pytest/pypy_test_failure_demo.py ============================================================================== --- pypy/branch/2.5-merge/pypy/tool/pytest/pypy_test_failure_demo.py (original) +++ pypy/branch/2.5-merge/pypy/tool/pytest/pypy_test_failure_demo.py Tue Oct 7 11:58:50 2008 @@ -22,5 +22,9 @@ raises(SyntaxError, int, "hello") def app_test_raises_doesnt(): - raises(ValueError, int, 3) + raises(ValueError, int, 3) + +def app_test_skip(): + skip("skipped test") + Modified: pypy/branch/2.5-merge/pypy/tool/test/test_conftest1.py ============================================================================== --- pypy/branch/2.5-merge/pypy/tool/test/test_conftest1.py (original) +++ pypy/branch/2.5-merge/pypy/tool/test/test_conftest1.py Tue Oct 7 11:58:50 2008 @@ -2,39 +2,24 @@ import py innertest = py.magic.autopath().dirpath('conftest1_innertest.py') -from py.__.test.terminal.terminal import TerminalSession -from py.__.test.outcome import Passed, Failed, Skipped +from py.__.test.testing import suptest -class TestPyPyTests: +class TestPyPyTests(suptest.InlineSession): def test_select_interplevel(self): - config = py.test.config._reparse([innertest, '-k', 'interplevel']) - session = TerminalSession(config, py.std.sys.stdout) - session.main() - l = session.getitemoutcomepairs(Passed) - assert len(l) == 2 - for item in l: - assert item[0].name in ('test_something', 'test_method') - #item = l[0][0] - #assert item.name == 'test_one' - l = session.getitemoutcomepairs(Skipped) - assert len(l) == 2 - for item in l: - assert item[0].name in ('app_test_something', 'test_method_app') + sorter = self.parse_and_run("-k", "interplevel", innertest) + passed, skipped, failed = sorter.listoutcomes() + assert len(passed) == 2 + assert not skipped and not failed + for repevent in passed: + assert repevent.colitem.name in ('test_something', 'test_method') def test_select_applevel(self): - config = py.test.config._reparse([innertest, '-k', 'applevel']) - session = TerminalSession(config, py.std.sys.stdout) - session.main() - l = session.getitemoutcomepairs(Passed) - assert len(l) == 2 - for item in l: - assert item[0].name in ('app_test_something', 'test_method_app') - #item = l[0][0] - #assert item.name == 'test_one' - l = session.getitemoutcomepairs(Skipped) - assert len(l) == 2 - for item in l: - assert item[0].name in ('test_something', 'test_method') + sorter = self.parse_and_run("-k", "applevel", innertest) + passed, skipped, failed = sorter.listoutcomes() + assert len(passed) == 2 + assert not skipped and not failed + for repevent in passed: + assert repevent.colitem.name in ('app_test_something', 'test_method_app') def XXX_test_appdirect(self): config = py.test.config._reparse([innertest, Modified: pypy/branch/2.5-merge/pypy/tool/test/test_pytestsupport.py ============================================================================== --- pypy/branch/2.5-merge/pypy/tool/test/test_pytestsupport.py (original) +++ pypy/branch/2.5-merge/pypy/tool/test/test_pytestsupport.py Tue Oct 7 11:58:50 2008 @@ -117,7 +117,7 @@ tdir = udir.ensure("t", dir=True) dest = tdir.join("test_expect.py") dest.write(source) - col = conftest.Module(dest) + col = conftest.Module(dest, config="dummy") result = col.run() assert len(result) == 1 @@ -138,7 +138,7 @@ dest = udir.join("test_expect_safefilename.py") dest.write(source) from pypy import conftest - col = conftest.Module(dest) + col = conftest.Module(dest, config="dummy") methcol = col.join('ExpectTestOne').join('()').join('test_one') name = 'test_expect_safefilename_ExpectTestOne_paren_test_one.py' assert methcol.safe_filename() == name From iko at codespeak.net Tue Oct 7 12:03:11 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Tue, 7 Oct 2008 12:03:11 +0200 (CEST) Subject: [pypy-svn] r58709 - pypy/branch/2.5-merge/lib-python/modified-2.5.1/test Message-ID: <20081007100311.B7D9B169EFA@codespeak.net> Author: iko Date: Tue Oct 7 12:03:11 2008 New Revision: 58709 Removed: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/string_tests.py Log: (iko, cfbolz) Modifications no longer needed From iko at codespeak.net Tue Oct 7 12:08:27 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Tue, 7 Oct 2008 12:08:27 +0200 (CEST) Subject: [pypy-svn] r58711 - pypy/branch/2.5-merge/lib-python/modified-2.5.1/test Message-ID: <20081007100827.6DF6D169F07@codespeak.net> Author: iko Date: Tue Oct 7 12:08:26 2008 New Revision: 58711 Removed: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/seq_tests.py Log: (iko,cfbolz) Modifications no longer needed From arigo at codespeak.net Tue Oct 7 12:12:45 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 12:12:45 +0200 (CEST) Subject: [pypy-svn] r58712 - pypy/branch/2.5-merge/lib-python Message-ID: <20081007101245.C681B169E55@codespeak.net> Author: arigo Date: Tue Oct 7 12:12:44 2008 New Revision: 58712 Modified: pypy/branch/2.5-merge/lib-python/conftest.py Log: Re-add support for "-k core". Modified: pypy/branch/2.5-merge/lib-python/conftest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/conftest.py (original) +++ pypy/branch/2.5-merge/lib-python/conftest.py Tue Oct 7 12:12:44 2008 @@ -74,15 +74,6 @@ return self._compiler #or pypy_option.compiler compiler = property(compiler) - def getoptions(self): - l = [] - for name in ['core']: - if getattr(self, name): - l.append(name) - for name in self.usemodules: - l.append(name) - return l - def ismodified(self): return modregrtestdir.join(self.basename).check() @@ -671,6 +662,13 @@ return exit_status, test_stdout, test_stderr + def _keywords(self): + lst = list(py.test.collect.Item._keywords(self)) + regrtest = self.parent.regrtest + if regrtest.core: + lst.append('core') + return lst + # # Sanity check (could be done more nicely too) # From arigo at codespeak.net Tue Oct 7 12:13:53 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 12:13:53 +0200 (CEST) Subject: [pypy-svn] r58713 - pypy/dist/lib-python Message-ID: <20081007101353.BDC10169E6F@codespeak.net> Author: arigo Date: Tue Oct 7 12:13:52 2008 New Revision: 58713 Modified: pypy/dist/lib-python/conftest.py Log: Merge r58712. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Tue Oct 7 12:13:52 2008 @@ -74,15 +74,6 @@ return self._compiler #or pypy_option.compiler compiler = property(compiler) - def getoptions(self): - l = [] - for name in ['core']: - if getattr(self, name): - l.append(name) - for name in self.usemodules: - l.append(name) - return l - def ismodified(self): return modregrtestdir.join(self.basename).check() @@ -671,6 +662,13 @@ return exit_status, test_stdout, test_stderr + def _keywords(self): + lst = list(py.test.collect.Item._keywords(self)) + regrtest = self.parent.regrtest + if regrtest.core: + lst.append('core') + return lst + # # Sanity check (could be done more nicely too) # From arigo at codespeak.net Tue Oct 7 12:42:48 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 12:42:48 +0200 (CEST) Subject: [pypy-svn] r58716 - pypy/branch/2.5-merge/pypy/lib Message-ID: <20081007104248.678AD169EF6@codespeak.net> Author: arigo Date: Tue Oct 7 12:42:47 2008 New Revision: 58716 Modified: pypy/branch/2.5-merge/pypy/lib/cPickle.py Log: The 'bin' argument was removed in pickle.py 2.5. Modified: pypy/branch/2.5-merge/pypy/lib/cPickle.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/cPickle.py (original) +++ pypy/branch/2.5-merge/pypy/lib/cPickle.py Tue Oct 7 12:42:47 2008 @@ -31,10 +31,10 @@ def getvalue(self): return self.__f and self.__f.getvalue() -def dump(obj, file, protocol=None, bin=None): - Pickler(file, protocol, bin).dump(obj) +def dump(obj, file, protocol=None): + Pickler(file, protocol).dump(obj) -def dumps(obj, protocol=None, bin=None): +def dumps(obj, protocol=None): file = StringIO() - Pickler(file, protocol, bin).dump(obj) + Pickler(file, protocol).dump(obj) return file.getvalue() From arigo at codespeak.net Tue Oct 7 12:55:55 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 12:55:55 +0200 (CEST) Subject: [pypy-svn] r58717 - in pypy/branch/2.5-merge/pypy/lib: . test2 Message-ID: <20081007105555.73DE9169F0D@codespeak.net> Author: arigo Date: Tue Oct 7 12:55:54 2008 New Revision: 58717 Modified: pypy/branch/2.5-merge/pypy/lib/array.py pypy/branch/2.5-merge/pypy/lib/test2/test_array.py Log: Test and fix: allow array.array objects to be pickled. Modified: pypy/branch/2.5-merge/pypy/lib/array.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/array.py (original) +++ pypy/branch/2.5-merge/pypy/lib/array.py Tue Oct 7 12:55:54 2008 @@ -289,6 +289,15 @@ else: return self.tolist() >= other.tolist() + def __reduce__(self): + dict = getattr(self, '__dict__', None) + data = self.tostring() + if data: + initargs = (self.typecode, data) + else: + initargs = (self.typecode,) + return (type(self), initargs, dict) + ##### list methods def append(self, x): Modified: pypy/branch/2.5-merge/pypy/lib/test2/test_array.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/test2/test_array.py (original) +++ pypy/branch/2.5-merge/pypy/lib/test2/test_array.py Tue Oct 7 12:55:54 2008 @@ -30,6 +30,14 @@ assert len(a) == 1 assert a.tolist() == [unichr(9999)] + def test_pickle(self): + import pickle + for content in [[56, -12, 34], []]: + a = self.array.array('i', content) + a2 = pickle.loads(pickle.dumps(a)) + assert type(a2) is self.array.array + assert list(a2) == content + class TestArrayOnTopOfCPython(BaseArrayTests): @@ -45,6 +53,9 @@ def test_unicode(self): py.test.skip("no 'u' type code in CPython's struct module") + def test_pickle(self): + py.test.skip("pickle getting confused by the hack in setup_class()") + class AppTestArray(BaseArrayTests): usemodules = ['struct'] From arigo at codespeak.net Tue Oct 7 13:09:10 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 13:09:10 +0200 (CEST) Subject: [pypy-svn] r58718 - in pypy/branch/2.5-merge/pypy/lib: . test2 Message-ID: <20081007110910.F19A7169E41@codespeak.net> Author: arigo Date: Tue Oct 7 13:09:06 2008 New Revision: 58718 Modified: pypy/branch/2.5-merge/pypy/lib/array.py pypy/branch/2.5-merge/pypy/lib/test2/test_array.py Log: Test and fix: array.array can now be subclassed, with new keyword arguments added in the subclass's __init__. Requires ad-hoc hacks in the base class's __new__, just like in CPython. Modified: pypy/branch/2.5-merge/pypy/lib/array.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/array.py (original) +++ pypy/branch/2.5-merge/pypy/lib/array.py Tue Oct 7 13:09:06 2008 @@ -91,8 +91,10 @@ """ __slots__ = ["typecode", "itemsize", "_data", "_descriptor", "__weakref__"] - def __new__(cls, typecode, initializer=[]): + def __new__(cls, typecode, initializer=[], **extrakwds): self = object.__new__(cls) + if cls is array and extrakwds: + raise TypeError("array() does not take keyword arguments") if not isinstance(typecode, str) or len(typecode) != 1: raise TypeError( "array() argument 1 must be char, not %s" % type(typecode)) Modified: pypy/branch/2.5-merge/pypy/lib/test2/test_array.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/test2/test_array.py (original) +++ pypy/branch/2.5-merge/pypy/lib/test2/test_array.py Tue Oct 7 13:09:06 2008 @@ -2,6 +2,7 @@ import autopath import py +from py.test import raises import struct from pypy.conftest import gettestobjspace @@ -31,13 +32,44 @@ assert a.tolist() == [unichr(9999)] def test_pickle(self): + import sys + if sys.version_info < (2, 5): + py.test.skip("array.array not picklable before python 2.5") import pickle + for content in [[56, -12, 34], []]: a = self.array.array('i', content) a2 = pickle.loads(pickle.dumps(a)) assert type(a2) is self.array.array assert list(a2) == content + def test_init_vs_new(self): + import sys + if sys.version_info < (2, 5): + py.test.skip("array.array constructor changed in 2.5") + class A(self.array.array): + def __init__(self, *args, **kwds): + self.args = args + self.kwds = kwds + + a = A('c', foo='bar') + assert a.args == ('c',) + assert a.kwds == {'foo': 'bar'} + a = A('i', range(10), some=42) + assert a.args == ('i', range(10)) + assert a.kwds == {'some': 42} + raises(TypeError, A) + raises(TypeError, A, 42) + raises(TypeError, A, 'i', [], []) + raises(TypeError, self.array.array, 'i', [], foo='bar') + + +class TestCPythonsOwnArray(BaseArrayTests): + + def setup_class(cls): + import array + cls.array = array + class TestArrayOnTopOfCPython(BaseArrayTests): From arigo at codespeak.net Tue Oct 7 13:10:17 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 13:10:17 +0200 (CEST) Subject: [pypy-svn] r58719 - pypy/branch/2.5-merge/lib-python/modified-2.5.1/test Message-ID: <20081007111017.7C6D4169E41@codespeak.net> Author: arigo Date: Tue Oct 7 13:10:16 2008 New Revision: 58719 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_array.py Log: This line *is* nonsense. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_array.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_array.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_array.py Tue Oct 7 13:10:16 2008 @@ -19,7 +19,7 @@ class ArraySubclassWithKwargs(array.array): def __init__(self, typecode, newarg=None): - array.array.__init__(typecode) + array.array.__init__(self, typecode) tests = [] # list to accumulate all tests typecodes = "cubBhHiIlLfd" From pedronis at codespeak.net Tue Oct 7 13:24:10 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 7 Oct 2008 13:24:10 +0200 (CEST) Subject: [pypy-svn] r58720 - pypy/build/bot2/pypybuildbot Message-ID: <20081007112410.C751E169E4D@codespeak.net> Author: pedronis Date: Tue Oct 7 13:24:08 2008 New Revision: 58720 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: progress on the lib-python builder Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Tue Oct 7 13:24:08 2008 @@ -105,5 +105,6 @@ description="lib-python test", command=["python", "pypy/test_all.py", "--pypy=pypy/translator/goal/pypy-c", - "--resultlog=cpython.log"], + "--resultlog=cpython.log", "--collectonly", + "lib-python"], logfiles={'pytestLog': 'cpython.log'})) From iko at codespeak.net Tue Oct 7 13:25:39 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Tue, 7 Oct 2008 13:25:39 +0200 (CEST) Subject: [pypy-svn] r58721 - pypy/branch/2.5-merge/lib-python/modified-2.5.1 Message-ID: <20081007112539.00758169E4D@codespeak.net> Author: iko Date: Tue Oct 7 13:25:39 2008 New Revision: 58721 Removed: pypy/branch/2.5-merge/lib-python/modified-2.5.1/subprocess.py Log: (iko,cfbolz) an equivalent fix is in 2.5.2 From arigo at codespeak.net Tue Oct 7 13:27:06 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 13:27:06 +0200 (CEST) Subject: [pypy-svn] r58722 - in pypy/branch/2.5-merge/pypy/objspace: . test Message-ID: <20081007112706.AD935169E4D@codespeak.net> Author: arigo Date: Tue Oct 7 13:27:05 2008 New Revision: 58722 Modified: pypy/branch/2.5-merge/pypy/objspace/descroperation.py pypy/branch/2.5-merge/pypy/objspace/test/test_descriptor.py Log: Test and fix: __hash__ could return subclasses of 'int' or 'long', but that should be handled just like regular ints or longs. Modified: pypy/branch/2.5-merge/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/descroperation.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/descroperation.py Tue Oct 7 13:27:05 2008 @@ -293,10 +293,18 @@ # XXX CPython has a special case for types with "__hash__ = None" # to produce a nicer error message, namely "unhashable type: 'X'". w_result = space.get_and_call_function(w_hash, w_obj) - if space.is_true(space.isinstance(w_result, space.w_int)): + w_resulttype = space.type(w_result) + if space.is_w(w_resulttype, space.w_int): return w_result - elif space.is_true(space.isinstance(w_result, space.w_long)): + elif space.is_w(w_resulttype, space.w_long): return space.hash(w_result) + elif space.is_true(space.isinstance(w_result, space.w_int)): + # be careful about subclasses of 'int'... + return space.wrap(space.int_w(w_result)) + elif space.is_true(space.isinstance(w_result, space.w_long)): + # be careful about subclasses of 'long'... + bigint = space.bigint_w(w_result) + return space.wrap(bigint.hash()) else: raise OperationError(space.w_TypeError, space.wrap("__hash__() should return an int or long")) Modified: pypy/branch/2.5-merge/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/test/test_descriptor.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/test/test_descriptor.py Tue Oct 7 13:27:05 2008 @@ -81,3 +81,22 @@ def __hash__(self): return 1 assert isinstance(hash(G()), int) + + # __hash__ can return a subclass of long, but the fact that it's + # a subclass is ignored + class mylong(long): + def __hash__(self): + return 0 + class H(object): + def __hash__(self): + return mylong(42) + assert hash(H()) == hash(42L) + + # don't return a subclass of int, either + class myint(int): + pass + class I(object): + def __hash__(self): + return myint(15) + assert hash(I()) == 15 + assert type(hash(I())) is int From iko at codespeak.net Tue Oct 7 13:29:13 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Tue, 7 Oct 2008 13:29:13 +0200 (CEST) Subject: [pypy-svn] r58723 - in pypy/branch/2.5-merge/lib-python/modified-2.5.1: . test Message-ID: <20081007112913.63753169E6E@codespeak.net> Author: iko Date: Tue Oct 7 13:29:12 2008 New Revision: 58723 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/doctest.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/sre_compile.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_codecs.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_compile.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_format.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_funcattrs.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_marshal.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_os.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_re.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_repr.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_set.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_tempfile.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_trace.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_unicodedata.py pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_urllib2.py Log: (iko,cfbolz) Apply 2.5.2 diff to modified std lib files Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/doctest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/doctest.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/doctest.py Tue Oct 7 13:29:12 2008 @@ -209,7 +209,10 @@ filename = _module_relative_path(package, filename) if hasattr(package, '__loader__'): if hasattr(package.__loader__, 'get_data'): - return package.__loader__.get_data(filename), filename + file_contents = package.__loader__.get_data(filename) + # get_data() opens files as 'rb', so one must do the equivalent + # conversion as universal newlines would do. + return file_contents.replace(os.linesep, '\n'), filename return open(filename).read(), filename def _indent(s, indent=4): @@ -317,8 +320,21 @@ """ def __init__(self, out): self.__out = out + self.__debugger_used = False pdb.Pdb.__init__(self, stdout=out) + def set_trace(self, frame=None): + self.__debugger_used = True + if frame is None: + frame = sys._getframe().f_back + pdb.Pdb.set_trace(self, frame) + + def set_continue(self): + # Calling set_continue unconditionally would break unit test + # coverage reporting, as Bdb.set_continue calls sys.settrace(None). + if self.__debugger_used: + pdb.Pdb.set_continue(self) + def trace_dispatch(self, *args): # Redirect stdout to the given stream. save_stdout = sys.stdout Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/sre_compile.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/sre_compile.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/sre_compile.py Tue Oct 7 13:29:12 2008 @@ -281,7 +281,7 @@ # To represent a big charset, first a bitmap of all characters in the # set is constructed. Then, this bitmap is sliced into chunks of 256 -# characters, duplicate chunks are eliminitated, and each chunk is +# characters, duplicate chunks are eliminated, and each chunk is # given a number. In the compiled expression, the charset is # represented by a 16-bit word sequence, consisting of one word for # the number of different chunks, a sequence of 256 bytes (128 words) @@ -526,7 +526,7 @@ indexgroup[i] = k return _sre.compile( - pattern, flags, code, + pattern, flags | p.pattern.flags, code, p.pattern.groups-1, groupindex, indexgroup ) Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_codecs.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_codecs.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_codecs.py Tue Oct 7 13:29:12 2008 @@ -27,7 +27,7 @@ class ReadTest(unittest.TestCase): def check_partial(self, input, partialresults): # get a StreamReader for the encoding and feed the bytestring version - # of input to the reader byte by byte. Read every available from + # of input to the reader byte by byte. Read everything available from # the StreamReader and check that the results equal the appropriate # entries from partialresults. q = Queue() @@ -430,6 +430,55 @@ # SF bug #1601501: check that the codec works with a buffer unicode("\xef\xbb\xbf", "utf-8-sig") + def test_bom(self): + d = codecs.getincrementaldecoder("utf-8-sig")() + s = u"spam" + self.assertEqual(d.decode(s.encode("utf-8-sig")), s) + + def test_stream_bom(self): + unistring = u"ABC\u00A1\u2200XYZ" + bytestring = codecs.BOM_UTF8 + "ABC\xC2\xA1\xE2\x88\x80XYZ" + + reader = codecs.getreader("utf-8-sig") + for sizehint in [None] + range(1, 11) + \ + [64, 128, 256, 512, 1024]: + istream = reader(StringIO.StringIO(bytestring)) + ostream = StringIO.StringIO() + while 1: + if sizehint is not None: + data = istream.read(sizehint) + else: + data = istream.read() + + if not data: + break + ostream.write(data) + + got = ostream.getvalue() + self.assertEqual(got, unistring) + + def test_stream_bare(self): + unistring = u"ABC\u00A1\u2200XYZ" + bytestring = "ABC\xC2\xA1\xE2\x88\x80XYZ" + + reader = codecs.getreader("utf-8-sig") + for sizehint in [None] + range(1, 11) + \ + [64, 128, 256, 512, 1024]: + istream = reader(StringIO.StringIO(bytestring)) + ostream = StringIO.StringIO() + while 1: + if sizehint is not None: + data = istream.read(sizehint) + else: + data = istream.read() + + if not data: + break + ostream.write(data) + + got = ostream.getvalue() + self.assertEqual(got, unistring) + class EscapeDecodeTest(unittest.TestCase): def test_empty(self): self.assertEquals(codecs.escape_decode(""), ("", 0)) @@ -916,7 +965,7 @@ self.assertEquals(f.readlines(), [u'\ud55c\n', u'\uae00']) class EncodedFileTest(unittest.TestCase): - + def test_basic(self): f = StringIO.StringIO('\xed\x95\x9c\n\xea\xb8\x80') ef = codecs.EncodedFile(f, 'utf-16-le', 'utf-8') Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_compile.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_compile.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_compile.py Tue Oct 7 13:29:12 2008 @@ -37,6 +37,9 @@ def test_syntax_error(self): self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec") + def test_none_keyword_arg(self): + self.assertRaises(SyntaxError, compile, "f(None=1)", "", "exec") + def test_duplicate_global_local(self): try: exec 'def f(a): global a; a = 1' Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_format.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_format.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_format.py Tue Oct 7 13:29:12 2008 @@ -1,5 +1,7 @@ from test.test_support import verbose, have_unicode, TestFailed import sys +from test.test_support import MAX_Py_ssize_t +maxsize = MAX_Py_ssize_t # test string formatting operator (I am not sure if this is being tested # elsewhere but, surely, some of the given cases are *not* tested because @@ -7,6 +9,7 @@ # test on unicode strings as well overflowok = 1 +overflowrequired = 0 def testformat(formatstr, args, output=None): if verbose: @@ -23,11 +26,16 @@ if verbose: print 'overflow (this is fine)' else: - if output and result != output: + if overflowrequired: if verbose: print 'no' - print "%s %% %s == %s != %s" %\ - (repr(formatstr), repr(args), repr(result), repr(output)) + print "overflow expected on %s %% %s" % \ + (repr(formatstr), repr(args)) + elif output and result != output: + if verbose: + print 'no' + print "%s %% %s == %s != %s" % \ + (repr(formatstr), repr(args), repr(result), repr(output)) else: if verbose: print 'yes' @@ -55,6 +63,14 @@ # test some ridiculously large precision, expect overflow testboth('%12.*f', (123456, 1.0)) +# check for internal overflow validation on length of precision +overflowrequired = 1 +testboth("%#.*g", (110, -1.e+100/3.)) +testboth("%#.*G", (110, -1.e+100/3.)) +testboth("%#.*f", (110, -1.e+100/3.)) +testboth("%#.*F", (110, -1.e+100/3.)) +overflowrequired = 0 + # Formatting of long integers. Overflow is not ok overflowok = 0 testboth("%x", 10L, "a") @@ -238,12 +254,12 @@ test_exc('%o', Foobar(), TypeError, "expected string or Unicode object, long found") -if sys.maxint == 2**31-1: +if maxsize == 2**31-1: # crashes 2.2.1 and earlier: try: - "%*d"%(sys.maxint, -127) + "%*d"%(maxsize, -127) except (MemoryError, OverflowError): pass # CPython raises MemoryError, but both CPython and PyPy raise # OverflowError for string concatenation else: - raise TestFailed, '"%*d"%(sys.maxint, -127) should fail' + raise TestFailed, '"%*d"%(maxsize, -127) should fail' Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_funcattrs.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_funcattrs.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_funcattrs.py Tue Oct 7 13:29:12 2008 @@ -242,6 +242,17 @@ verify(c[0].__class__.__name__ == "cell") # don't have a type object handy cantset(f, "func_closure", c) +def test_empty_cell(): + def f(): print a + try: + f.func_closure[0].cell_contents + except ValueError: + pass + else: + raise TestFailed, "shouldn't be able to read an empty cell" + + a = 12 + def test_func_doc(): def f(): pass verify(f.__doc__ is None) @@ -385,6 +396,7 @@ def testmore(): test_func_closure() + test_empty_cell() test_func_doc() test_func_globals() test_func_name() Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_itertools.py Tue Oct 7 13:29:12 2008 @@ -5,6 +5,8 @@ import sys import operator import random +maxsize = test_support.MAX_Py_ssize_t +minsize = -maxsize-1 def onearg(x): 'Test function of one argument' @@ -52,7 +54,7 @@ self.assertEqual(take(2, zip('abc',count(3))), [('a', 3), ('b', 4)]) self.assertRaises(TypeError, count, 2, 3) self.assertRaises(TypeError, count, 'a') - self.assertRaises(OverflowError, list, islice(count(sys.maxint-5), 10)) + self.assertRaises(OverflowError, list, islice(count(maxsize-5), 10)) c = count(3) self.assertEqual(repr(c), 'count(3)') c.next() @@ -288,7 +290,7 @@ self.assertRaises((TypeError, ValueError), islice, xrange(10), 1, 'a') self.assertRaises((TypeError, ValueError), islice, xrange(10), 'a', 1, 1) self.assertRaises((TypeError, ValueError), islice, xrange(10), 1, 'a', 1) - self.assertEqual(len(list(islice(count(), 1, 10, sys.maxint))), 1) + self.assertEqual(len(list(islice(count(), 1, 10, maxsize))), 1) def test_takewhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_marshal.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_marshal.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_marshal.py Tue Oct 7 13:29:12 2008 @@ -208,6 +208,30 @@ except Exception: pass + def test_loads_recursion(self): + s = 'c' + ('X' * 4*4) + '{' * 2**20 + self.assertRaises(ValueError, marshal.loads, s) + + def test_recursion_limit(self): + # Create a deeply nested structure. + head = last = [] + # The max stack depth should match the value in Python/marshal.c. + MAX_MARSHAL_STACK_DEPTH = 2000 + for i in range(MAX_MARSHAL_STACK_DEPTH - 2): + last.append([0]) + last = last[-1] + + # Verify we don't blow out the stack with dumps/load. + data = marshal.dumps(head) + new_head = marshal.loads(data) + # Don't use == to compare objects, it can exceed the recursion limit. + self.assertEqual(len(new_head), len(head)) + self.assertEqual(len(new_head[0]), len(head[0])) + self.assertEqual(len(new_head[-1]), len(head[-1])) + + last.append([0]) + self.assertRaises(ValueError, marshal.dumps, head) + def test_main(): test_support.run_unittest(IntTestCase, FloatTestCase, Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_os.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_os.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_os.py Tue Oct 7 13:29:12 2008 @@ -226,10 +226,20 @@ # Restrict test to Win32, since there is no guarantee other # systems support centiseconds if sys.platform == 'win32': - def test_1565150(self): - t1 = 1159195039.25 - os.utime(self.fname, (t1, t1)) - self.assertEquals(os.stat(self.fname).st_mtime, t1) + def get_file_system(path): + import os + root = os.path.splitdrive(os.path.realpath("."))[0] + '\\' + import ctypes + kernel32 = ctypes.windll.kernel32 + buf = ctypes.create_string_buffer("", 100) + if kernel32.GetVolumeInformationA(root, None, 0, None, None, None, buf, len(buf)): + return buf.value + + if get_file_system(test_support.TESTFN) == "NTFS": + def test_1565150(self): + t1 = 1159195039.25 + os.utime(self.fname, (t1, t1)) + self.assertEquals(os.stat(self.fname).st_mtime, t1) def test_1686475(self): # Verify that an open file can be stat'ed Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_re.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_re.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_re.py Tue Oct 7 13:29:12 2008 @@ -83,6 +83,31 @@ self.assertEqual(re.sub('\r\n', '\n', 'abc\r\ndef\r\n'), 'abc\ndef\n') + def test_bug_1140(self): + # re.sub(x, y, u'') should return u'', not '', and + # re.sub(x, y, '') should return '', not u''. + # Also: + # re.sub(x, y, unicode(x)) should return unicode(y), and + # re.sub(x, y, str(x)) should return + # str(y) if isinstance(y, str) else unicode(y). + for x in 'x', u'x': + for y in 'y', u'y': + z = re.sub(x, y, u'') + self.assertEqual(z, u'') + self.assertEqual(type(z), unicode) + # + z = re.sub(x, y, '') + self.assertEqual(z, '') + self.assertEqual(type(z), str) + # + z = re.sub(x, y, unicode(x)) + self.assertEqual(z, y) + self.assertEqual(type(z), unicode) + # + z = re.sub(x, y, str(x)) + self.assertEqual(z, y) + self.assertEqual(type(z), type(y)) + def test_sub_template_numeric_escape(self): # bug 776311 and friends self.assertEqual(re.sub('x', r'\0', 'x'), '\0') @@ -618,7 +643,37 @@ for typecode in 'cbBuhHiIlLfd': a = array.array(typecode) self.assertEqual(re.compile("bla").match(a), None) - self.assertEqual(re.compile("").match(a).groups(), ()) + self.assertEqual(re.compile("").match(a).groups(), ()) + + def test_inline_flags(self): + # Bug #1700 + upper_char = unichr(0x1ea0) # Latin Capital Letter A with Dot Bellow + lower_char = unichr(0x1ea1) # Latin Small Letter A with Dot Bellow + + p = re.compile(upper_char, re.I | re.U) + q = p.match(lower_char) + self.assertNotEqual(q, None) + + p = re.compile(lower_char, re.I | re.U) + q = p.match(upper_char) + self.assertNotEqual(q, None) + + p = re.compile('(?i)' + upper_char, re.U) + q = p.match(lower_char) + self.assertNotEqual(q, None) + + p = re.compile('(?i)' + lower_char, re.U) + q = p.match(upper_char) + self.assertNotEqual(q, None) + + p = re.compile('(?iu)' + upper_char) + q = p.match(lower_char) + self.assertNotEqual(q, None) + + p = re.compile('(?iu)' + lower_char) + q = p.match(upper_char) + self.assertNotEqual(q, None) + def run_re_tests(): from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_repr.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_repr.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_repr.py Tue Oct 7 13:29:12 2008 @@ -10,6 +10,7 @@ from test.test_support import run_unittest from repr import repr as r # Don't shadow builtin repr +from repr import Repr def nestedTuple(nesting): @@ -34,6 +35,18 @@ expected = repr(s)[:13] + "..." + repr(s)[-14:] eq(r(s), expected) + def test_tuple(self): + eq = self.assertEquals + eq(r((1,)), "(1,)") + + t3 = (1, 2, 3) + eq(r(t3), "(1, 2, 3)") + + r2 = Repr() + r2.maxtuple = 2 + expected = repr(t3)[:-2] + "...)" + eq(r2.repr(t3), expected) + def test_container(self): from array import array from collections import deque @@ -187,6 +200,16 @@ x = classmethod(C.foo) self.failUnless(repr(x).startswith(' 0: + x -= 1 + self.run_and_compare( + while_example, + [(0, 'call'), + (2, 'line'), + (3, 'line'), + (4, 'line'), + (3, 'line'), + (4, 'line'), + (3, 'line'), + (3, 'return')]) + + def test_16_blank_lines(self): + exec("def f():\n" + "\n" * 256 + " pass") + self.run_and_compare( + f, + [(0, 'call'), + (257, 'line'), + (257, 'return')]) + + class RaisingTraceFuncTestCase(unittest.TestCase): def trace(self, frame, event, arg): """A trace function that raises an exception in response to a Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_unicodedata.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_unicodedata.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_unicodedata.py Tue Oct 7 13:29:12 2008 @@ -214,6 +214,10 @@ count += 1 self.assert_(count >= 10) # should have tested at least the ASCII digits + def test_bug_1704793(self): + if sys.maxunicode == 65535: + self.assertRaises(KeyError, self.db.lookup, "GOTHIC LETTER FAIHU") + def test_main(): test.test_support.run_unittest( UnicodeMiscTest, Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_urllib2.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_urllib2.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/test_urllib2.py Tue Oct 7 13:29:12 2008 @@ -381,6 +381,12 @@ class OpenerDirectorTests(unittest.TestCase): + def test_add_non_handler(self): + class NonHandler(object): + pass + self.assertRaises(TypeError, + OpenerDirector().add_handler, NonHandler()) + def test_badly_named_methods(self): # test work-around for three methods that accidentally follow the # naming conventions for handler methods From pedronis at codespeak.net Tue Oct 7 13:29:26 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 7 Oct 2008 13:29:26 +0200 (CEST) Subject: [pypy-svn] r58724 - pypy/build/bot2/pypybuildbot Message-ID: <20081007112926.90704169E6E@codespeak.net> Author: pedronis Date: Tue Oct 7 13:29:25 2008 New Revision: 58724 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: try a real run instead Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Tue Oct 7 13:29:25 2008 @@ -37,7 +37,7 @@ description = ["translating"] descriptionDone = ["translation"] - command = ["echo", "python", "translate.py", "--batch"] + command = ["python", "translate.py", "--batch"] translationTarget = "targetpypystandalone" def __init__(self, translationArgs, targetArgs, @@ -105,6 +105,5 @@ description="lib-python test", command=["python", "pypy/test_all.py", "--pypy=pypy/translator/goal/pypy-c", - "--resultlog=cpython.log", "--collectonly", - "lib-python"], + "--resultlog=cpython.log", "lib-python"], logfiles={'pytestLog': 'cpython.log'})) From arigo at codespeak.net Tue Oct 7 13:40:51 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 13:40:51 +0200 (CEST) Subject: [pypy-svn] r58725 - pypy/branch/2.5-merge/pypy/objspace/std/test Message-ID: <20081007114051.D607A169E4A@codespeak.net> Author: arigo Date: Tue Oct 7 13:40:51 2008 New Revision: 58725 Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_strutil.py Log: Check in failing tests (skipped). Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py Tue Oct 7 13:40:51 2008 @@ -1,3 +1,4 @@ +import py import sys from pypy.objspace.std import intobject as iobj from pypy.objspace.std.objspace import FailedToImplement @@ -321,6 +322,14 @@ raises(TypeError, int, 1, 10) raises(TypeError, int, '5', '9') + def test_int_largenums(self): + py.test.skip("in-progress") + import sys + for x in [-sys.maxint-1, -1, sys.maxint]: + y = int(str(x)) + assert y == x + assert type(y) is int + def test_shift_zeros(self): assert (1 << 0) == 1 assert (1 >> 0) == 1 Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_strutil.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_strutil.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_strutil.py Tue Oct 7 13:40:51 2008 @@ -91,6 +91,13 @@ raises(ParseStringOverflowError, string_to_int, str(sys.maxint*17)) + def test_string_to_int_not_overflow(self): + py.test.skip("in-progress") + import sys + for x in [-sys.maxint-1, sys.maxint]: + y = string_to_int(str(x)) + assert y == x + def test_string_to_int_base_error(self): space = self.space cases = [('1', 1), From iko at codespeak.net Tue Oct 7 13:47:28 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Tue, 7 Oct 2008 13:47:28 +0200 (CEST) Subject: [pypy-svn] r58726 - in pypy/branch/2.5-merge: lib-python/2.5.1 lib-python/2.5.2 lib-python/modified-2.5.1 lib-python/modified-2.5.2 lib-python/modified-2.5.2/test pypy/module/sys pypy/tool pypy/tool/pytest Message-ID: <20081007114728.E8EE2169E71@codespeak.net> Author: iko Date: Tue Oct 7 13:47:28 2008 New Revision: 58726 Added: pypy/branch/2.5-merge/lib-python/2.5.2/ (props changed) - copied from r58724, pypy/branch/2.5-merge/lib-python/2.5.1/ pypy/branch/2.5-merge/lib-python/modified-2.5.2/ (props changed) - copied from r58724, pypy/branch/2.5-merge/lib-python/modified-2.5.1/ Removed: pypy/branch/2.5-merge/lib-python/2.5.1/ pypy/branch/2.5-merge/lib-python/modified-2.5.1/ Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/__init__.py pypy/branch/2.5-merge/pypy/module/sys/version.py pypy/branch/2.5-merge/pypy/tool/pytest/confpath.py pypy/branch/2.5-merge/pypy/tool/stdlib___future__.py Log: (iko,cfbolz) rename 2.5.1 -> 2.5.2 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/__init__.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.1/test/__init__.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/__init__.py Tue Oct 7 13:47:28 2008 @@ -4,7 +4,7 @@ 'test' package from CPython. This assumes that sys.path is configured to contain -'lib-python/modified-2.5.1' before 'lib-python/2.5.1'. +'lib-python/modified-2.5.2' before 'lib-python/2.5.2'. """ from pkgutil import extend_path Modified: pypy/branch/2.5-merge/pypy/module/sys/version.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/sys/version.py (original) +++ pypy/branch/2.5-merge/pypy/module/sys/version.py Tue Oct 7 13:47:28 2008 @@ -4,7 +4,7 @@ import os -CPYTHON_VERSION = (2, 5, 1, "alpha", 42) +CPYTHON_VERSION = (2, 5, 2, "alpha", 42) CPYTHON_API_VERSION = 1012 PYPY_VERSION = (1, 0, 0, "alpha", '?') Modified: pypy/branch/2.5-merge/pypy/tool/pytest/confpath.py ============================================================================== --- pypy/branch/2.5-merge/pypy/tool/pytest/confpath.py (original) +++ pypy/branch/2.5-merge/pypy/tool/pytest/confpath.py Tue Oct 7 13:47:28 2008 @@ -7,5 +7,5 @@ testresultdir = distdir.join('testresult') assert pypydir.check(dir=1) libpythondir = distdir.join('lib-python') -regrtestdir = libpythondir.join('2.5.1', 'test') -modregrtestdir = libpythondir.join('modified-2.5.1', 'test') +regrtestdir = libpythondir.join('2.5.2', 'test') +modregrtestdir = libpythondir.join('modified-2.5.2', 'test') Modified: pypy/branch/2.5-merge/pypy/tool/stdlib___future__.py ============================================================================== --- pypy/branch/2.5-merge/pypy/tool/stdlib___future__.py (original) +++ pypy/branch/2.5-merge/pypy/tool/stdlib___future__.py Tue Oct 7 13:47:28 2008 @@ -2,7 +2,7 @@ def load_module(): import py - module_path = py.path.local(__file__).dirpath().dirpath().dirpath('lib-python/2.5.1/__future__.py') + module_path = py.path.local(__file__).dirpath().dirpath().dirpath('lib-python/2.5.2/__future__.py') execfile(str(module_path), globals()) load_module() From xoraxax at codespeak.net Tue Oct 7 13:52:30 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 13:52:30 +0200 (CEST) Subject: [pypy-svn] r58727 - pypy/dist/pypy/rpython/lltypesystem Message-ID: <20081007115230.446EB169E94@codespeak.net> Author: xoraxax Date: Tue Oct 7 13:52:29 2008 New Revision: 58727 Modified: pypy/dist/pypy/rpython/lltypesystem/rffi.py Log: (antocuni, xoraxax) Propagate the module name in llexternal, can be used for reporting. Modified: pypy/dist/pypy/rpython/lltypesystem/rffi.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rffi.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rffi.py Tue Oct 7 13:52:29 2008 @@ -124,6 +124,7 @@ """ % locals()) miniglobals = {'aroundstate': aroundstate, 'funcptr': funcptr, + '__name__': __name__, # for module name propagation } exec source.compile() in miniglobals call_external_function = miniglobals['call_external_function'] From witulski at codespeak.net Tue Oct 7 13:54:13 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Tue, 7 Oct 2008 13:54:13 +0200 (CEST) Subject: [pypy-svn] r58728 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081007115413.C7B08169EA0@codespeak.net> Author: witulski Date: Tue Oct 7 13:54:13 2008 New Revision: 58728 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: (witulski,fijal) Implemented emit_moves usage for correct loops. Some cleanups. Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Tue Oct 7 13:54:13 2008 @@ -258,20 +258,18 @@ method = getattr(self, "_INC"+op1.to_string()) method(op1) - # op1 must be a register - def JMP(self,op1): + # 4 length of the immediate + def JMP(self,want_jump_to): #method = getattr(self, "_JMP"+op1.to_string()) - #method(op1) - print hex(self.tell()),": JMP to",hex(self.tell()+op1) + #method(op1) self.write("\xE9") - self.writeImm32(op1) + self.writeImm32(want_jump_to-self.tell()-4) - # op1 is and 32bit displ - def JNE(self,op1): - print hex(self.tell()),": JNE to",hex(self.tell()+op1) + # 4 length of the immediate + def JNE(self,want_jump_to): self.write("\x0F") self.write("\x85") - self.writeImm32(op1) + self.writeImm32(want_jump_to-self.tell()-4) def OR(self, op1, op2): @@ -368,8 +366,6 @@ # parse to string and cut "0x" off # fill with zeros if to short y = "0"*(10-len(x))+x[2:len(x)] - #print "y:",y - #y = "00000000" assert len(y) == 8 self.write(chr(int(y[6:8],16))) self.write(chr(int(y[4:6],16))) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Tue Oct 7 13:54:13 2008 @@ -6,6 +6,7 @@ from pypy.rpython.lltypesystem import llmemory, lltype from pypy.jit.codegen.ia32.objmodel import LL_TO_GENVAR from pypy.jit.codegen.model import GenLabel +from pypy.jit.codegen.emit_moves import emit_moves, emit_moves_safe @@ -55,14 +56,24 @@ self.startaddr = startaddr self.arg_positions = arg_positions self.stackdepth = stackdepth + +class MoveEmitter(object): + def __init__(self, builder): + self.builder = builder + self.moves = [] + + def create_fresh_location(self): + return self.builder.allocate_register().reg + def emit_move(self, source, target): + self.moves.append((source, target)) class Builder(model.GenBuilder): MC_SIZE = 65536 #FIXME: The MemCodeBuild. is not opend in an _open method - def __init__(self): + def __init__(self, used_registers=[]): self.mc = InMemoryCodeBuilder(self.MC_SIZE) #callee-saved registers are commented out self.freeregisters ={ @@ -81,6 +92,8 @@ # "r14":None, # "r15":None, } + for reg in used_registers: + self.allocate_register(reg.reg) def _open(self): pass @@ -88,13 +101,11 @@ @specialize.arg(1) def genop1(self, opname, gv_arg): genmethod = getattr(self, 'op_' + opname) - print hex(self.mc.tell()),":",opname," ",gv_arg.to_string() return genmethod(gv_arg) @specialize.arg(1) def genop2(self, opname, gv_arg1, gv_arg2): genmethod = getattr(self, 'op_' + opname) - print hex(self.mc.tell()),":",opname," ",gv_arg1.to_string()," ",gv_arg2.to_string() return genmethod(gv_arg1, gv_arg2) op_int_add = make_two_argument_method("ADD") @@ -147,24 +158,13 @@ # def op_int_invert(self, gv_x): # return self.mc.NOT(gv_x) - - - #FIXME: can only jump 32bit - # -6 : length of the jne instruction - def jump_if_true(self, gv_condition, args_for_jump_gv): - targetbuilder = Builder() - self.mc.CMP(gv_condition, Immediate32(0)) - displ = self.calc_32bit_displacement(self.mc.tell(),targetbuilder.mc.tell()) - self.mc.JNE(displ-6) - #targetbuilder.come_from(self.mc, 'JNE') - return targetbuilder def op_int_gt(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) # You can not use every register for # 8 bit operations, so you have to # choose rax,rcx or rdx - # TODO: rcx rdx + # TODO: use also rcx rdx gv_z = self.allocate_register("rax") self.mc.SETG(Register8("al")) return Register64("rax") @@ -199,32 +199,60 @@ self.mc.SETGE(Register8("al")) return Register64("rax") + + def _compute_moves(self, outputargs_gv, targetargs_gv): + tar2src = {} + tar2loc = {} + src2loc = {} + for i in range(len(outputargs_gv)): + target_gv = targetargs_gv[i].reg + source_gv = outputargs_gv[i].reg + tar2src[target_gv] = source_gv + tar2loc[target_gv] = target_gv + src2loc[source_gv] = source_gv + movegen = MoveEmitter(self) + emit_moves(movegen, [target_gv.reg for target_gv in targetargs_gv], + tar2src, tar2loc, src2loc) + return movegen.moves + + + #FIXME: can only jump 32bit + #FIXME: imm8 insted of imm32? + def jump_if_true(self, gv_condition, args_for_jump_gv): + targetbuilder = Builder(args_for_jump_gv) + self.mc.CMP(gv_condition, Immediate32(0)) + self.mc.JNE(targetbuilder.mc.tell()) + # args_for_jump contain the registers which are used + # from the caller block. These registers cant be used by + # the targetbuilder + + #targetbuilder.come_from(self.mc, 'JNE') + return targetbuilder + def finish_and_return(self, sigtoken, gv_returnvar): #self.mc.write("\xB8\x0F\x00\x00\x00") - print hex(self.mc.tell()),": RET" self._open() if not gv_returnvar == None:#check void return self.mc.MOV(Register64("rax"), gv_returnvar) self.mc.RET() self._close() - #FIXME: uses 32bit displ + #FIXME: uses 32bit displ + #FIXME: neg. displacement??? # if the label is greater than 32bit # it must be in a register - # -5 length of the jmp instruction def finish_and_goto(self, outputargs_gv, target): - import pdb;pdb.set_trace() + #import pdb;pdb.set_trace() self._open() #gv_x = self.allocate_register() #self.mc.MOV(gv_x,Immediate64(target.startaddr)) - #self.mc.JMP(gv_x) - - displ = self.calc_32bit_displacement(self.mc.tell(),target.startaddr) - self.mc.JMP(displ-5) - - #self.mc.RET() - + #self.mc.JMP(gv_x) + moves = self._compute_moves(outputargs_gv, target.arg_positions) + for source_gv, target_gv in moves: + self.mc.MOV(Register64(source_gv), Register64(target_gv)) + self.mc.JMP(target.startaddr) self._close() + def allocate_register(self, register=None): if register is None: @@ -244,16 +272,13 @@ for i in range(len(args_gv)): if isinstance(args_gv[i],model.GenConst): gv_x = self.allocate_register() - self.mc.MOV(gv_x, argsv_gv[i]) + self.mc.MOV(gv_x, args_gv[i]) args_gv[i] = gv_x L = Label(self.mc.tell(), args_gv, 0) return L def _close(self): self.mc.done() - - def calc_32bit_displacement(self, curr_addr, want_jump_to): - return want_jump_to-curr_addr class RX86_64GenOp(model.AbstractRGenOp): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Tue Oct 7 13:54:13 2008 @@ -22,8 +22,12 @@ builder.end() return gv_push_pop -#FIXME: Jumps ever (CMP BUG) + #TODO: result of ops +# if x>y: +# return y+3 +# else: +# return y+1 def make_jne(rgenop): sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) builder, gv_jne, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "jne") @@ -44,7 +48,7 @@ builder, gv_jmp, [gv_x] = rgenop.newgraph(sigtoken, "jmp") builder.start_writing() builder.genop1("int_inc",gv_x) - builder.finish_and_goto("",Label(builder.mc.tell()+6, [], 0)) + builder.finish_and_goto("",Label(builder.mc.tell()+11, [], 0)) b=0 for b in range(a): builder.genop1("int_inc",gv_x) @@ -285,28 +289,28 @@ assert res == 1 res = fnptr(23) assert res == 0 - #cmp_function = make_cmp(self.RGenOp(), "int_eq") - #fnptr = self.cast(cmp_function,2) - #res = fnptr(3,4) # 3==4? - #assert res == 0 # false - #res = fnptr(4,3) - #assert res == 0 - #res = fnptr(4,4) - #assert res == 1 - #res = fnptr(4,0) - #assert res == 0 - #res = fnptr(-4,0) - #assert res == 0 - #res = fnptr(184467440737095516,184467440737095516) - #assert res == 1 - #res = fnptr(252,-4) - #assert res == 0 - #res = fnptr(-4,252) - #assert res == 0 - #res = fnptr(244,756) - #assert res == 0 - #res = fnptr(-1,9223372036854775807) #FFFF.... != 7FFF... - #assert res == 0 + cmp_function = make_cmp(self.RGenOp(), "int_eq") + fnptr = self.cast(cmp_function,2) + res = fnptr(3,4) # 3==4? + assert res == 0 # false + res = fnptr(4,3) + assert res == 0 + res = fnptr(4,4) + assert res == 1 + res = fnptr(4,0) + assert res == 0 + res = fnptr(-4,0) + assert res == 0 + res = fnptr(184467440737095516,184467440737095516) + assert res == 1 + res = fnptr(252,-4) + assert res == 0 + res = fnptr(-4,252) + assert res == 0 + res = fnptr(244,756) + assert res == 0 + res = fnptr(-1,9223372036854775807) #FFFF.... != 7FFF... + assert res == 0 def test_not_equal(self): cmp_function = make_cmp(self.RGenOp(), "int_ne") @@ -411,6 +415,7 @@ result = fnptr(12,14) assert result == 15 + # x = x+y-1 def test_jmp(self): jmp_function = make_jmp(self.RGenOp(),3) fnptr = self.cast(jmp_function,1) From pedronis at codespeak.net Tue Oct 7 13:54:29 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 7 Oct 2008 13:54:29 +0200 (CEST) Subject: [pypy-svn] r58729 - pypy/build/bot2/pypybuildbot Message-ID: <20081007115429.6E967169EA0@codespeak.net> Author: pedronis Date: Tue Oct 7 13:54:29 2008 New Revision: 58729 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: go for allworkingmodules Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Tue Oct 7 13:54:29 2008 @@ -99,7 +99,7 @@ setup_steps(platform, self) - self.addStep(Translate(["-O0"], ["-no-allworkingmodules"])) + self.addStep(Translate(["-O0"], [])) self.addStep(shell.ShellCommand( description="lib-python test", From xoraxax at codespeak.net Tue Oct 7 13:55:58 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 13:55:58 +0200 (CEST) Subject: [pypy-svn] r58730 - pypy/dist/pypy/translator/c Message-ID: <20081007115558.9EF1E169EAC@codespeak.net> Author: xoraxax Date: Tue Oct 7 13:55:58 2008 New Revision: 58730 Modified: pypy/dist/pypy/translator/c/funcgen.py Log: (antocuni, xoraxax) Preserve all constants after a funcgen implemented a function to be able to use the constants in reporting. Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Tue Oct 7 13:55:58 2008 @@ -30,7 +30,7 @@ __slots__ = """graph db gcpolicy exception_policy more_ll_values - vars + vars all_cached_consts lltypes functionname blocknum @@ -73,6 +73,7 @@ # # NOTE: cannot use dictionaries with Constants as keys, because # Constants may hash and compare equal but have different lltypes + self.all_cached_consts = None # will be filled after implementation_end mix = [self.graph.getreturnvar()] self.more_ll_values = [] for block in self.graph.iterblocks(): @@ -136,6 +137,7 @@ yield self.graph def implementation_end(self): + self.all_cached_consts = list(self.allconstantvalues()) self.lltypes = None self.vars = None self.blocknum = None From hpk at codespeak.net Tue Oct 7 14:05:53 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 7 Oct 2008 14:05:53 +0200 (CEST) Subject: [pypy-svn] r58731 - pypy/branch/2.5-merge/lib-python Message-ID: <20081007120553.B93C1169EF8@codespeak.net> Author: hpk Date: Tue Oct 7 14:05:53 2008 New Revision: 58731 Modified: pypy/branch/2.5-merge/lib-python/conftest.py Log: try a nicer representation of failures Modified: pypy/branch/2.5-merge/lib-python/conftest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/conftest.py (original) +++ pypy/branch/2.5-merge/lib-python/conftest.py Tue Oct 7 14:05:53 2008 @@ -553,6 +553,9 @@ import getpass class ReallyRunFileExternal(py.test.collect.Item): + class ExternalFailure(Exception): + """Failure in running subprocess""" + def getinvocation(self, regrtest): fspath = regrtest.getfspath() python = sys.executable @@ -611,10 +614,13 @@ regrtest = self.parent.regrtest exit_status, test_stdout, test_stderr = self.getresult(regrtest) if exit_status: - time.sleep(0.5) # time for a Ctrl-C to reach us :-) - print >>sys.stdout, test_stdout - print >>sys.stderr, test_stderr - py.test.fail("running test failed, see stderr output below") + raise self.ExternalFailure(test_stdout, test_stderr) + + def repr_failure(self, excinfo, outerr): + if not excinfo.errisinstance(self.ExternalFailure): + return super(ReallyRunFileExternal, self).repr_failure(excinfo, outerr) + out, err = excinfo.value.args + return out + err def getstatusouterr(self, cmd): tempdir = py.test.ensuretemp(self.fspath.basename) From pedronis at codespeak.net Tue Oct 7 14:07:19 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 7 Oct 2008 14:07:19 +0200 (CEST) Subject: [pypy-svn] r58732 - pypy/build/bot2 Message-ID: <20081007120719.3465F168451@codespeak.net> Author: pedronis Date: Tue Oct 7 14:07:18 2008 New Revision: 58732 Modified: pypy/build/bot2/TODO Log: update TODO Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Tue Oct 7 14:07:18 2008 @@ -2,15 +2,16 @@ for specifying possibly branches - improve summary page (defined in pypybuildbot/summary.page), support querying/slicing - by builders/revisions(/branches), formatting and css + by builders, formatting and css - some kind of progress information for a run + +- report translation failures in the summary somehow + - support for better information in case of runner-level killed hanging tests - build/support for running cpython on tests, adaptations to produce structured logs and be compatible - with the py.lib trunk are probably necessary for lib-python/conftest.py + with the py.lib trunk are probably necessary for lib-python/conftest.py TESTING - pypy-c py.test -A support -- fix pypy conftests not to use deprecated interfaces - From pedronis at codespeak.net Tue Oct 7 14:07:48 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 7 Oct 2008 14:07:48 +0200 (CEST) Subject: [pypy-svn] r58733 - pypy/build/bot2 Message-ID: <20081007120748.00CE2169E83@codespeak.net> Author: pedronis Date: Tue Oct 7 14:07:48 2008 New Revision: 58733 Modified: pypy/build/bot2/TODO Log: another TODO Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Tue Oct 7 14:07:48 2008 @@ -15,3 +15,4 @@ - pypy-c py.test -A support +- look into why the full summary page but not single rev is slowish From pedronis at codespeak.net Tue Oct 7 14:22:16 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 7 Oct 2008 14:22:16 +0200 (CEST) Subject: [pypy-svn] r58734 - pypy/build/bot2 Message-ID: <20081007122216.BE7CF169F7F@codespeak.net> Author: pedronis Date: Tue Oct 7 14:22:12 2008 New Revision: 58734 Modified: pypy/build/bot2/TODO Log: another todo Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Tue Oct 7 14:22:12 2008 @@ -16,3 +16,6 @@ - pypy-c py.test -A support - look into why the full summary page but not single rev is slowish + +- have a way for the involved tool to avoid color escapes even when there's a tty (because of buildbot pty usage) + From witulski at codespeak.net Tue Oct 7 14:23:35 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Tue, 7 Oct 2008 14:23:35 +0200 (CEST) Subject: [pypy-svn] r58735 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081007122335.195A5169F7A@codespeak.net> Author: witulski Date: Tue Oct 7 14:23:35 2008 New Revision: 58735 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: IDIV sign extended(Test pass) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Tue Oct 7 14:23:35 2008 @@ -231,7 +231,11 @@ def AND(self, op1, op2): method = getattr(self, "_AND"+op1.to_string()+op2.to_string()) method(op1, op2) - + + def CDQ(self): + self.write("\x48") + self.write("\x99") + def CMP(self, op1, op2): #import pdb;pdb.set_trace() method = getattr(self, "_CMP"+op1.to_string()+op2.to_string()) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Tue Oct 7 14:23:35 2008 @@ -137,12 +137,11 @@ return gv_x # IDIV RDX:RAX with QWREG - # FIXME: supports only RAX with QWREG + # supports only RAX (64bit) with QWREG def op_int_div(self, gv_x, gv_y): gv_z = self.allocate_register("rax") - gv_w = self.allocate_register("rdx") self.mc.MOV(gv_z, gv_x) - self.mc.XOR(gv_w, gv_w) + self.mc.CDQ() #sign extention self.mc.IDIV(gv_y) return gv_z Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Tue Oct 7 14:23:35 2008 @@ -34,7 +34,7 @@ builder.start_writing() gv_z = builder.genop2("int_gt", gv_x, gv_y) builder.mc.CMP(gv_z, rgenop.genconst(1)) - builder.mc.JNE(6) + builder.mc.JNE(builder.mc.tell()+6+6) #length of the jne(6 byte) + length of tow incs(3 byte) builder.genop1("int_inc",gv_y)#not executed if x<=y builder.genop1("int_inc",gv_y)#not executed if x<=y builder.genop1("int_inc",gv_y) From jlg at codespeak.net Tue Oct 7 14:25:51 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Tue, 7 Oct 2008 14:25:51 +0200 (CEST) Subject: [pypy-svn] r58736 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081007122551.1127F169E96@codespeak.net> Author: jlg Date: Tue Oct 7 14:25:50 2008 New Revision: 58736 Modified: pypy/branch/2.5-merge/pypy/objspace/std/strutil.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_strutil.py Log: (arigo, jlg) fix for int overflow cornercase Modified: pypy/branch/2.5-merge/pypy/objspace/std/strutil.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/strutil.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/strutil.py Tue Oct 7 14:25:50 2008 @@ -101,12 +101,11 @@ while True: digit = p.next_digit() if digit == -1: - try: - result = ovfcheck(p.sign * result) - except OverflowError: - raise ParseStringOverflowError(p) - else: - return result + return result + + if p.sign == -1: + digit = -digit + try: result = ovfcheck(result * base) result = ovfcheck(result + digit) Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py Tue Oct 7 14:25:50 2008 @@ -323,7 +323,6 @@ raises(TypeError, int, '5', '9') def test_int_largenums(self): - py.test.skip("in-progress") import sys for x in [-sys.maxint-1, -1, sys.maxint]: y = int(str(x)) Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_strutil.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_strutil.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_strutil.py Tue Oct 7 14:25:50 2008 @@ -92,7 +92,6 @@ str(sys.maxint*17)) def test_string_to_int_not_overflow(self): - py.test.skip("in-progress") import sys for x in [-sys.maxint-1, sys.maxint]: y = string_to_int(str(x)) From xoraxax at codespeak.net Tue Oct 7 14:30:20 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 14:30:20 +0200 (CEST) Subject: [pypy-svn] r58737 - pypy/dist/pypy/translator/tool Message-ID: <20081007123020.0FF32169F05@codespeak.net> Author: xoraxax Date: Tue Oct 7 14:30:19 2008 New Revision: 58737 Modified: pypy/dist/pypy/translator/tool/staticsizereport.py Log: (cfbolz, antocuni, xoraxax) Add reporting for static data in RPython programs by module. Can be used e.g. on the pdb prompt after source generation. Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Tue Oct 7 14:30:19 2008 @@ -1,10 +1,34 @@ from __future__ import division -from pypy.rpython.lltypesystem.lltype import typeOf, _ptr, Ptr +from pypy.rpython.lltypesystem.lltype import typeOf, _ptr, Ptr, ContainerType from pypy.rpython.lltypesystem import llmemory from pypy.rpython.memory.lltypelayout import convert_offset_to_int -def guess_size(obj): + +def guess_module(graph): + func = getattr(graph, 'func', None) + name = '' + if func is not None: + newname = func.func_globals.get('__name__', None) + if newname is not None: + name = newname + else: + if func.__module__: + name = func.__module__ + return name + + +def values_to_nodes(database, values): + nodes = [] + for value in values: + if isinstance(typeOf(value), Ptr) and isinstance(typeOf(value._obj), ContainerType): + node = database.getcontainernode(value._obj) + if node.nodekind != 'func': + nodes.append(node) + return nodes + + +def guess_size_obj(obj): TYPE = typeOf(obj) ptr = _ptr(Ptr(TYPE), obj) if TYPE._is_varsize(): @@ -22,24 +46,94 @@ return convert_offset_to_int(llmemory.sizeof(TYPE, length)) +def guess_size(database, node, recursive=None): + obj = node.obj + size = guess_size_obj(obj) + if recursive is None: + return size + if node in recursive: + return 0 + recursive.add(node) + for dep in values_to_nodes(database, node.enum_dependencies()): + recursive.add(dep) + size += guess_size(database, dep, recursive) + return size + + def by_lltype(obj): return typeOf(obj) -def group_static_size(database, grouper=by_lltype): +def group_static_size(database, nodes, grouper=by_lltype, recursive=None): totalsize = {} numobjects = {} - for node in database.globalcontainers(): + for node in nodes: obj = node.obj group = grouper(obj) - totalsize[group] = totalsize.get(group, 0) + guess_size(obj) + totalsize[group] = totalsize.get(group, 0) + guess_size(database, node, recursive) numobjects[group] = numobjects.get(group, 0) + 1 return totalsize, numobjects -def print_static_size(database, grouper=by_lltype): - totalsize, numobjects = group_static_size(database, grouper) +def make_report_static_size(database, nodes, grouper, recursive=None): + totalsize, numobjects = group_static_size(database, nodes, grouper, recursive) l = [(size, key) for key, size in totalsize.iteritems()] l.sort() l.reverse() + sizesum = 0 + report = [] for size, key in l: - print key, size, numobjects[key], size / numobjects[key] + sizesum += size + report.append((key, size, numobjects[key], size / numobjects[key])) + return sizesum, report + +def format_report_line(line): + return str(line[0])[:50] + " " + " ".join([str(x) for x in line[1:]]) + + +def print_report_static_size(database, grouper=by_lltype): + " Reports all objects with a specified grouper. " + _, report = report_static_size(database.globalcontainers(), grouper) + for line in report: + print format_report_line(line) + + +def print_aggregated_values_by_module_and_type(database, count_modules_separately=False): + " Reports all objects by module and by lltype. " + modules = {} + reports = [] + funcnodes = [node for node in database.globalcontainers() + if node.nodekind == "func"] + # extract all prebuilt nodes per module + for node in funcnodes: + graph = getattr(node.obj, 'graph', None) + if not graph: + continue + nodes_set = modules.setdefault(guess_module(graph), set()) + assert len(node.funcgens) == 1 + nodes_set.update(values_to_nodes(database, node.funcgens[0].all_cached_consts)) + modules = modules.items() + # make sure that gc modules are reported latest to avoid them eating all objects + def gc_module_key(tup): + if "module.gc" in tup[0]: + return ("\xff", ) + tup + return tup + modules.sort(key=gc_module_key) + + # report sizes per module + seen = set() + for modulename, nodes in modules: + if count_modules_separately: + seen = set() + if not nodes: + continue + size, report = make_report_static_size(database, nodes, by_lltype, seen) + reports.append((size, modulename, report)) + reports.sort() + reports.reverse() + for size, modulename, report in reports: + if not size: + continue + print "########### %i %s ####################################" % (size, modulename) + for line in report: + print " " * 4 + format_report_line(line) + print From arigo at codespeak.net Tue Oct 7 14:31:43 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 14:31:43 +0200 (CEST) Subject: [pypy-svn] r58738 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081007123143.2BB12169F7E@codespeak.net> Author: arigo Date: Tue Oct 7 14:31:42 2008 New Revision: 58738 Modified: pypy/branch/2.5-merge/pypy/objspace/std/inttype.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py Log: (jlg, arigo) Test and fix for subclasses of 'int' that override __int__(). Modified: pypy/branch/2.5-merge/pypy/objspace/std/inttype.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/inttype.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/inttype.py Tue Oct 7 14:31:42 2008 @@ -55,7 +55,7 @@ value = 0 if w_base is None: # check for easy cases - if isinstance(w_value, W_IntObject): + if type(w_value) is W_IntObject: value = w_value.intval elif space.is_true(space.isinstance(w_value, space.w_str)): try: Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_intobject.py Tue Oct 7 14:31:42 2008 @@ -417,7 +417,16 @@ class b(object): pass - raises((AttributeError,TypeError), long, b()) + raises((AttributeError,TypeError), long, b()) + + def test_override___int__(self): + class myint(int): + def __int__(self): + return 42 + assert int(myint(21)) == 42 + class myotherint(int): + pass + assert int(myotherint(21)) == 21 def test_getnewargs(self): assert 0 .__getnewargs__() == (0,) From arigo at codespeak.net Tue Oct 7 14:34:26 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 14:34:26 +0200 (CEST) Subject: [pypy-svn] r58739 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081007123426.29480169F85@codespeak.net> Author: arigo Date: Tue Oct 7 14:34:25 2008 New Revision: 58739 Modified: pypy/branch/2.5-merge/pypy/objspace/std/longtype.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_longobject.py Log: (jlg, arigo) Test and fix for subclasses of 'long' that override __long__(). Modified: pypy/branch/2.5-merge/pypy/objspace/std/longtype.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/longtype.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/longtype.py Tue Oct 7 14:34:25 2008 @@ -8,7 +8,7 @@ w_value = w_x # 'x' is the keyword argument name in CPython if w_base is None: # check for easy cases - if isinstance(w_value, W_LongObject): + if type(w_value) is W_LongObject: pass elif space.is_true(space.isinstance(w_value, space.w_str)): try: Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_longobject.py Tue Oct 7 14:34:25 2008 @@ -194,3 +194,12 @@ raises(OverflowError, float, huge) raises(OverflowError, operator.truediv, huge, 3) raises(OverflowError, operator.truediv, huge, 3L) + + def test_override___long__(self): + class mylong(long): + def __long__(self): + return 42L + assert long(mylong(21)) == 42L + class myotherlong(long): + pass + assert long(myotherlong(21)) == 21L From arigo at codespeak.net Tue Oct 7 14:43:08 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 14:43:08 +0200 (CEST) Subject: [pypy-svn] r58740 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081007124308.1C394169F16@codespeak.net> Author: arigo Date: Tue Oct 7 14:43:07 2008 New Revision: 58740 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py Log: Need some gc.collect()s to make sure that the reference goes away. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py Tue Oct 7 14:43:07 2008 @@ -407,6 +407,7 @@ p = proxy(a) self.assertEqual(getattr(p, '__class__'), type(b)) del a + import gc; gc.collect(); gc.collect(); gc.collect() self.assertRaises(ReferenceError, getattr, p, '__class__') def test_StopIteration(self): From arigo at codespeak.net Tue Oct 7 14:43:27 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 14:43:27 +0200 (CEST) Subject: [pypy-svn] r58741 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081007124327.246EE169F22@codespeak.net> Author: arigo Date: Tue Oct 7 14:43:26 2008 New Revision: 58741 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_builtin.py Log: Disabling an implementation detail test. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_builtin.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_builtin.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_builtin.py Tue Oct 7 14:43:26 2008 @@ -1438,10 +1438,13 @@ self.assertRaises(ValueError, range, 1, 2, 0) self.assertRaises(ValueError, range, a, a + 1, long(0)) - class badzero(int): - def __cmp__(self, other): - raise RuntimeError - self.assertRaises(RuntimeError, range, a, a + 1, badzero(1)) + # XXX the following seems to test a complete implementation + # detail (it is probably checking a specific error path + # in the C code) + #class badzero(int): + # def __cmp__(self, other): + # raise RuntimeError + #self.assertRaises(RuntimeError, range, a, a + 1, badzero(1)) # Reject floats when it would require PyLongs to represent. # (smaller floats still accepted, but deprecated) From cami at codespeak.net Tue Oct 7 14:52:08 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Tue, 7 Oct 2008 14:52:08 +0200 (CEST) Subject: [pypy-svn] r58742 - pypy/dist/pypy/lang/gameboy/debug Message-ID: <20081007125208.7385A169F39@codespeak.net> Author: cami Date: Tue Oct 7 14:52:07 2008 New Revision: 58742 Modified: pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py Log: removed all gui and lib sdl dependency from the debug test Modified: pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py Tue Oct 7 14:52:07 2008 @@ -287,7 +287,8 @@ def compare_memory(self, name, expected, new): self.print_check(name+" length", len(expected), len(new)) if len(expected) != len(new): return - for address in range(len(expected)): + # only check every 3rd in order to speed things up + for address in range(len(expected), 3): self.print_check(name+" value at "+hex(address), \ expected[address], new[address]) Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Tue Oct 7 14:52:07 2008 @@ -17,7 +17,7 @@ ROM_PATH = str(py.magic.autopath().dirpath().dirpath())+"/rom" filename = "/Users/cami/Ausbildung/08_UNIBE_FS/bachelor/docs/roms/DieMaus.gb" filename = ROM_PATH + "/rom9/rom9.gb" -SOCKET_PORT = 55686 +SOCKET_PORT = 55687 skipExecs = 22545 skipExecs = 0 @@ -38,13 +38,15 @@ gameBoy = GameBoyDebugImplementation(SOCKET_PORT, skipExecs, DebugRpcXmlMemory) try: gameBoy.load_cartridge_file(str(filename)) - except: + except Exception, error: gameBoy.load_cartridge_file(str(filename), verify=False) print "Cartridge is Corrupted!" try: + pdb.set_trace() gameBoy.mainLoop() - except: + except Exception, error: print "stopped" + print error # ------------------------------------------------------------------------------ Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py Tue Oct 7 14:52:07 2008 @@ -13,11 +13,13 @@ class GameBoyDebugImplementation(GameBoyImplementation): def __init__(self, debuggerPort, skipExecs=0, memory_class=DebugSocketMemory): - GameBoy.__init__(self) + GameBoyImplementation.__init__(self) self.cpu = DebugCPU(self.interrupt, self) self.init_sdl() self.memory = memory_class(self, debuggerPort, skipExecs) + def init_sdl(self): + pass; def create_drivers(self): # make sure only the debug drivers are implemented @@ -25,9 +27,12 @@ self.joypad_driver = JoypadDriverDebugImplementation() self.video_driver = VideoDriverDebugImplementation() self.sound_driver = SoundDriverImplementation() - + + def emulate_cycle(self): + self.emulate(constants.GAMEBOY_CLOCK >> 2) def handle_execution_error(self, error): + GameBoyImplementation.handle_execution_error(self, error) print error print "closing socket connections" pdb.set_trace() From arigo at codespeak.net Tue Oct 7 15:00:41 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 15:00:41 +0200 (CEST) Subject: [pypy-svn] r58743 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081007130041.0A71E169E9D@codespeak.net> Author: arigo Date: Tue Oct 7 15:00:41 2008 New Revision: 58743 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_builtin.py Log: (jlg, arigo) Fix irrelevant failures by generalizing the test. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_builtin.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_builtin.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_builtin.py Tue Oct 7 15:00:41 2008 @@ -246,10 +246,10 @@ self.assertRaises(TypeError, compile) self.assertRaises(ValueError, compile, 'print 42\n', '', 'badmode') self.assertRaises(ValueError, compile, 'print 42\n', '', 'single', 0xff) - self.assertRaises(TypeError, compile, chr(0), 'f', 'exec') + self.assertRaises((TypeError, SyntaxError), compile, chr(0), 'f', 'exec') if have_unicode: compile(unicode('print u"\xc3\xa5"\n', 'utf8'), '', 'exec') - self.assertRaises(TypeError, compile, unichr(0), 'f', 'exec') + self.assertRaises((TypeError, SyntaxError), compile, unichr(0), 'f', 'exec') self.assertRaises(ValueError, compile, unicode('a = 1'), 'f', 'bad') def test_delattr(self): @@ -432,9 +432,9 @@ execfile(TESTFN, globals, locals) self.assertEqual(locals['z'], 2) - unlink(TESTFN) self.assertRaises(TypeError, execfile) self.assertRaises(TypeError, execfile, TESTFN, {}, ()) + unlink(TESTFN) import os self.assertRaises(IOError, execfile, os.curdir) self.assertRaises(IOError, execfile, "I_dont_exist") @@ -560,8 +560,12 @@ if have_unicode: self.assertEqual(float(unicode(" 3.14 ")), 3.14) self.assertEqual(float(unicode(" \u0663.\u0661\u0664 ",'raw-unicode-escape')), 3.14) - # Implementation limitation in PyFloat_FromString() - self.assertRaises(ValueError, float, unicode("1"*10000)) + try: + value = float(unicode("1"*10000)) + except ValueError: + pass # Implementation limitation in PyFloat_FromString() + else: + self.assert_(value > 1e300) # infinite @run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE') def test_float_with_comma(self): From cami at codespeak.net Tue Oct 7 15:11:33 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Tue, 7 Oct 2008 15:11:33 +0200 (CEST) Subject: [pypy-svn] r58744 - pypy/dist/pypy/lang/gameboy/debug Message-ID: <20081007131133.640BC169F5F@codespeak.net> Author: cami Date: Tue Oct 7 15:11:32 2008 New Revision: 58744 Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Log: changed classpath Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Tue Oct 7 15:11:32 2008 @@ -53,7 +53,7 @@ JMARIO_DIR = str(py.magic.autopath().dirpath().dirpath()\ .dirpath().dirpath()\ .dirpath().dirpath()) + "/jmario" -JAVA_CLASSPATH =[JMARIO_DIR+"/bin/", +JAVA_CLASSPATH =[JMARIO_DIR+"/bin/", JMARIO_DIR+"/build/", JMARIO_DIR+"/lib/xmlrpc-client-3.1.jar", JMARIO_DIR+"/lib/xmlrpc-common-3.1.jar", JMARIO_DIR+"/lib/ws-commons-util-1.0.2.jar", From cami at codespeak.net Tue Oct 7 15:19:44 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Tue, 7 Oct 2008 15:19:44 +0200 (CEST) Subject: [pypy-svn] r58746 - pypy/dist/pypy/lang/gameboy Message-ID: <20081007131944.020E2169F00@codespeak.net> Author: cami Date: Tue Oct 7 15:19:44 2008 New Revision: 58746 Modified: pypy/dist/pypy/lang/gameboy/gameboy.py pypy/dist/pypy/lang/gameboy/gameboy_implementation.py pypy/dist/pypy/lang/gameboy/timer.py pypy/dist/pypy/lang/gameboy/video_mode.py Log: separated libsdl specific stuff in seprated methods Modified: pypy/dist/pypy/lang/gameboy/gameboy.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/gameboy.py (original) +++ pypy/dist/pypy/lang/gameboy/gameboy.py Tue Oct 7 15:19:44 2008 @@ -125,8 +125,8 @@ def write(self, address, data): receiver = self.get_receiver(address) if receiver is None: - return - #raise Exception("invalid read address given") + raise Exception("invalid read address given") + #return receiver.write(address, data) if address == constants.STAT or address == 0xFFFF: self.cpu.handle_pending_interrupts() @@ -134,8 +134,8 @@ def read(self, address): receiver = self.get_receiver(address) if receiver is None: - return 0xFF - #raise Exception("invalid read address given") + # raise Exception("invalid read address given") + return 0xFF return receiver.read(address) def print_receiver_msg(self, address, name): Modified: pypy/dist/pypy/lang/gameboy/gameboy_implementation.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/gameboy_implementation.py (original) +++ pypy/dist/pypy/lang/gameboy/gameboy_implementation.py Tue Oct 7 15:19:44 2008 @@ -30,25 +30,26 @@ self.joypad_driver = JoypadDriverImplementation() self.video_driver = VideoDriverImplementation() self.sound_driver = SoundDriverImplementation() - def mainLoop(self): self.reset() self.is_running = True try: while self.is_running: - self.handle_events() - self.emulate(constants.GAMEBOY_CLOCK >> 2) - RSDL.Delay(1) - except : - self.is_running = False - lltype.free(self.event, flavor='raw') - RSDL.Quit() - self.handle_execution_error() + self.emulate_cycle() + except Exception, error: + self.is_running = False + self.handle_execution_error(error) return 0 - def handle_execution_error(self): - pass + def emulate_cycle(self): + self.handle_events() + self.emulate(constants.GAMEBOY_CLOCK >> 2) + RSDL.Delay(1) + + def handle_execution_error(self, error): + lltype.free(self.event, flavor='raw') + RSDL.Quit() def handle_events(self): self.poll_event() Modified: pypy/dist/pypy/lang/gameboy/timer.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/timer.py (original) +++ pypy/dist/pypy/lang/gameboy/timer.py Tue Oct 7 15:19:44 2008 @@ -146,21 +146,8 @@ if self.timer_counter == 0x00: self.timer_counter = self.timer_modulo self.timer_interrupt_flag.set_pending() - - #def emulate_timer(self, ticks): - # if (self.timer_control & 0x04) == 0: - # return - # self.timer_cycles -= ticks - # if self.timer_cycles > 0: return - # count = int(math.ceil(-self.timer_cycles / self.timer_clock)) + 1 - # self.timer_cycles += self.timer_clock*count - # # check for zero pass - # if (self.timer_counter + count) > 0xFF: - # self.interrupt.raise_interrupt(constants.TIMER) - # zero_passes = math.ceil(self.timer_counter / count) - # self.timer_counter = (self.timer_modulo + count - zero_passes ) % (0xFF +1) - # else: - # self.timer_counter = (self.timer_counter + count) % (0xFF +1) + + # CLOCK DRIVER ----------------------------------------------------------------- class Clock(object): Modified: pypy/dist/pypy/lang/gameboy/video_mode.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/video_mode.py (original) +++ pypy/dist/pypy/lang/gameboy/video_mode.py Tue Oct 7 15:19:44 2008 @@ -15,11 +15,9 @@ Exception.__init__(self, "") class Mode(object): - """ The two lower STAT bits show the current status of the LCD controller. """ - def __init__(self, video): self.video = video self.reset() @@ -56,7 +54,6 @@ the CPU can access both the display RAM (8000h-9FFFh) and OAM (FE00h-FE9Fh) """ - def reset(self): self.h_blank_interrupt = False @@ -104,7 +101,6 @@ display is disabled) and the CPU can access both the display RAM (8000h-9FFFh) and OAM (FE00h-FE9Fh) """ - def reset(self): self.v_blank_interrupt = False @@ -168,7 +164,6 @@ The CPU access OAM memory (FE00h-FE9Fh) during this period. """ - def reset(self): self.oam_interrupt = False @@ -198,7 +193,6 @@ The CPU access OAM and VRAM during this period. CGB Mode: Cannot access Palette Data (FF69,FF6B) either. """ - def reset(self): pass From cfbolz at codespeak.net Tue Oct 7 15:21:47 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 7 Oct 2008 15:21:47 +0200 (CEST) Subject: [pypy-svn] r58747 - pypy/dist/pypy/doc Message-ID: <20081007132147.B82C5169F07@codespeak.net> Author: cfbolz Date: Tue Oct 7 15:21:47 2008 New Revision: 58747 Modified: pypy/dist/pypy/doc/maemo.txt Log: fix rest problem Modified: pypy/dist/pypy/doc/maemo.txt ============================================================================== --- pypy/dist/pypy/doc/maemo.txt (original) +++ pypy/dist/pypy/doc/maemo.txt Tue Oct 7 15:21:47 2008 @@ -83,15 +83,16 @@ Creating an target emulating N810/Maemo environment +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Now we instruct scratchbox to define a target suitable for emulating the N810/Maemo device:: - -Login to the virtual environment and invoke : +Now we instruct scratchbox to define a target suitable for emulating the +N810/Maemo device: + +Login to the virtual environment and invoke:: /scratchbox/login sb-menu this brings up an interactive menu, you need to *setup* a new target, -you may name it "ARMEL" and then you need to select +you may name it "ARMEL" and then you need to select:: compiler: cs2007q3-glibc2.5-arm7 devkits: cputransp, perl, svn From cami at codespeak.net Tue Oct 7 15:24:04 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Tue, 7 Oct 2008 15:24:04 +0200 (CEST) Subject: [pypy-svn] r58748 - pypy/dist/pypy/lang/gameboy/debug Message-ID: <20081007132404.46674169F07@codespeak.net> Author: cami Date: Tue Oct 7 15:24:03 2008 New Revision: 58748 Modified: pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Log: changed the skip count for the memory check Modified: pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py Tue Oct 7 15:24:03 2008 @@ -288,7 +288,7 @@ self.print_check(name+" length", len(expected), len(new)) if len(expected) != len(new): return # only check every 3rd in order to speed things up - for address in range(len(expected), 3): + for address in range(0, len(expected), 3): self.print_check(name+" value at "+hex(address), \ expected[address], new[address]) @@ -327,7 +327,7 @@ if self.pending_steps > 0: self.pending_steps -= 1 return - #self.prompt_for_user_input() + self.prompt_for_user_input() def prompt_for_user_input(self): if self.showed_skip_message_count < 2: Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Tue Oct 7 15:24:03 2008 @@ -42,11 +42,11 @@ gameBoy.load_cartridge_file(str(filename), verify=False) print "Cartridge is Corrupted!" try: - pdb.set_trace() gameBoy.mainLoop() except Exception, error: print "stopped" print error + pdb.set_trace() # ------------------------------------------------------------------------------ From fijal at codespeak.net Tue Oct 7 15:29:18 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 7 Oct 2008 15:29:18 +0200 (CEST) Subject: [pypy-svn] r58749 - pypy/branch/2.5-merge/pypy/interpreter Message-ID: <20081007132918.4BD1B169F15@codespeak.net> Author: fijal Date: Tue Oct 7 15:29:17 2008 New Revision: 58749 Modified: pypy/branch/2.5-merge/pypy/interpreter/function.py Log: (fijal, arigo) Be a bit saner about comparisons of bound methods (2.5 compatible) Modified: pypy/branch/2.5-merge/pypy/interpreter/function.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/function.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/function.py Tue Oct 7 15:29:17 2008 @@ -438,7 +438,7 @@ else: if other.w_instance is None: return space.w_False - if not space.is_w(self.w_instance, other.w_instance): + if not space.eq_w(self.w_instance, other.w_instance): return space.w_False return space.eq(self.w_function, other.w_function) From hpk at codespeak.net Tue Oct 7 15:30:20 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 7 Oct 2008 15:30:20 +0200 (CEST) Subject: [pypy-svn] r58750 - in pypy/build/bot2: . wyvern-html Message-ID: <20081007133020.13233169F25@codespeak.net> Author: hpk Date: Tue Oct 7 15:30:20 2008 New Revision: 58750 Added: pypy/build/bot2/wyvern-html/ pypy/build/bot2/wyvern-html/buildbot.css - copied unchanged from r58739, pypy/build/bot2/wyvern_buildbot.css pypy/build/bot2/wyvern-html/index.html - copied unchanged from r58739, pypy/build/bot2/wyvern_index.html pypy/build/bot2/wyvern-html/robots.txt - copied unchanged from r58739, pypy/build/bot2/wyvern_robots.txt Removed: pypy/build/bot2/wyvern_buildbot.css pypy/build/bot2/wyvern_index.html pypy/build/bot2/wyvern_robots.txt Modified: pypy/build/bot2/master.cfg Log: (pedronis,hpk) move html files into own dir, add debugging env for image Modified: pypy/build/bot2/master.cfg ============================================================================== --- pypy/build/bot2/master.cfg (original) +++ pypy/build/bot2/master.cfg Tue Oct 7 15:30:20 2008 @@ -1,4 +1,4 @@ -import sys, os +import sys, os, socket # checkout bot2 in the home dir of the master sys.path.append(os.path.expanduser('~/bot2/')) from pypybuildbot.util import load @@ -7,7 +7,12 @@ httpPortNumber = 8099 # slavename -> password -passwords = load('slaveinfo').passwords - +slaveinfo = load('slaveinfo') +passwords = slaveinfo.passwords execfile(os.path.expanduser('~/bot2/pypybuildbot/master.py')) + +if socket.gethostname() != "wyvern": # for debugging + for builderdict in BuildmasterConfig['builders']: + builderdict["slavenames"] = ['localhost'] + BuildmasterConfig['buildbotURL'] = "http://localhost:%d/" % (httpPortNumber) From cfbolz at codespeak.net Tue Oct 7 15:41:13 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 7 Oct 2008 15:41:13 +0200 (CEST) Subject: [pypy-svn] r58751 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081007134113.B993B169F25@codespeak.net> Author: cfbolz Date: Tue Oct 7 15:41:13 2008 New Revision: 58751 Modified: pypy/branch/2.5-merge/pypy/objspace/std/setobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Log: (iko, cfbolz): make repr of set guard against recursion Modified: pypy/branch/2.5-merge/pypy/objspace/std/setobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/setobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/setobject.py Tue Oct 7 15:41:13 2008 @@ -632,16 +632,37 @@ hash__Frozenset(space, w_set) app = gateway.applevel(""" - def repr__Set(s): - return '%s(%s)' % (s.__class__.__name__, [x for x in s]) + def setrepr(currently_in_repr, s): + 'The app-level part of repr().' + set_id = id(s) + if set_id in currently_in_repr: + return 'set(...)' + currently_in_repr[set_id] = 1 + try: + return '%s(%s)' % (s.__class__.__name__, [x for x in s]) + finally: + try: + del currently_in_repr[set_id] + except: + pass +""", filename=__file__) + +setrepr = app.interphook("setrepr") + +def repr__Set(space, w_set): + ec = space.getexecutioncontext() + w_currently_in_repr = ec._py_repr + if w_currently_in_repr is None: + w_currently_in_repr = ec._py_repr = space.newdict() + return setrepr(space, w_currently_in_repr, w_set) +app = gateway.applevel(""" def reduce__Set(s): dict = getattr(s,'__dict__', None) return (s.__class__, (tuple(s),), dict) """, filename=__file__) -repr__Set = app.interphook('repr__Set') repr__Frozenset = app.interphook('repr__Set') set_reduce__Set = app.interphook('reduce__Set') Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Tue Oct 7 15:41:13 2008 @@ -71,3 +71,15 @@ assert set('abc') > frozenset('ab') assert not (set('abc') < frozenset('abc')) assert not (set('abc') > frozenset('abc')) + + def test_recursive_repr(self): + class A(object): + def __init__(self, s): + self.s = s + def __repr__(self): + return repr(self.s) + + s = set([1, 2, 3]) + s.add(A(s)) + assert repr(s) == "set([1, 2, 3, set(...)])" + From arigo at codespeak.net Tue Oct 7 15:43:48 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 15:43:48 +0200 (CEST) Subject: [pypy-svn] r58752 - pypy/branch/2.5-merge/lib-python Message-ID: <20081007134348.C3A40169F26@codespeak.net> Author: arigo Date: Tue Oct 7 15:43:48 2008 New Revision: 58752 Modified: pypy/branch/2.5-merge/lib-python/failure_list.txt Log: Paste an updated list of failures. Modified: pypy/branch/2.5-merge/lib-python/failure_list.txt ============================================================================== --- pypy/branch/2.5-merge/lib-python/failure_list.txt (original) +++ pypy/branch/2.5-merge/lib-python/failure_list.txt Tue Oct 7 15:43:48 2008 @@ -1,8 +1,129 @@ +arigo at wyvern ~/svn/pypy/branch/2.5-merge/lib-python/modified-2.5.2/test $ py.test --pypy=/home/arigo/pypysrc/compiled/pypy-c-58675-2.5-O1 -k core --tb=no +inserting into sys.path: /home/arigo/svn/pypy/branch/2.5-merge +================================================================ test session starts ================================================================ +HOSTUP: localhost-0 linux2 /usr/bin/python - Python 2.4.4-final-0 -test_descr - cannot easily complete this; after another quick review, the failures - left are mostly "don't care" internal details. +test___all__.py . +../../2.5.2/test/test___future__.py . +test_array.py . +../../2.5.2/test/test_atexit.py . +../../2.5.2/test/test_augassign.py . +../../2.5.2/test/test_binop.py . +../../2.5.2/test/test_bisect.py . +../../2.5.2/test/test_bool.py . +test_bufio.py . +test_builtin.py . +../../2.5.2/test/test_call.py . +../../2.5.2/test/test_charmapcodec.py . +test_class.py . +../../2.5.2/test/test_cmath.py . +../../2.5.2/test/test_codeccallbacks.py F +test_codecs.py F +test_codeop.py . +../../2.5.2/test/test_coercion.py F +../../2.5.2/test/test_compare.py . +test_compile.py F +test_complex.py . +../../2.5.2/test/test_contains.py . +test_copy.py . +../../2.5.2/test/test_copy_reg.py . +test_cpickle.py F +../../2.5.2/test/test_decorators.py . +test_deque.py F +test_descr.py F +test_descrtut.py . +test_dict.py F +../../2.5.2/test/test_dircache.py . +../../2.5.2/test/test_dummy_thread.py . +../../2.5.2/test/test_dummy_threading.py . +test_enumerate.py . +../../2.5.2/test/test_eof.py F +test_exceptions.py F +../../2.5.2/test/test_extcall.py F +test_file.py F +../../2.5.2/test/test_filecmp.py . +../../2.5.2/test/test_fileinput.py . +../../2.5.2/test/test_fnmatch.py . +test_format.py F +../../2.5.2/test/test_fpformat.py . +test_funcattrs.py F +../../2.5.2/test/test_future.py . +../../2.5.2/test/test_future1.py . +../../2.5.2/test/test_future2.py . +../../2.5.2/test/test_future3.py . +test_generators.py F +test_genexps.py F +../../2.5.2/test/test_getopt.py f +../../2.5.2/test/test_glob.py . +../../2.5.2/test/test_global.py . +../../2.5.2/test/test_grammar.py F +../../2.5.2/test/test_hash.py . +../../2.5.2/test/test_hashlib.py f +../../2.5.2/test/test_heapq.py . +../../2.5.2/test/test_hexoct.py . +../../2.5.2/test/test_imp.py . +../../2.5.2/test/test_import.py f +../../2.5.2/test/test_importhooks.py F +../../2.5.2/test/test_isinstance.py F +test_iter.py . +../../2.5.2/test/test_iterlen.py F +test_itertools.py F +../../2.5.2/test/test_list.py F +../../2.5.2/test/test_long.py F +../../2.5.2/test/test_long_future.py . +../../2.5.2/test/test_longexp.py . +test_marshal.py F +../../2.5.2/test/test_math.py . +test_module.py . +../../2.5.2/test/test_multibytecodec_support.py . +test_mutants.py . +../../2.5.2/test/test_new.py F +../../2.5.2/test/test_opcodes.py . +test_operations.py . +../../2.5.2/test/test_operator.py F +test_os.py . +test_parser.py F +../../2.5.2/test/test_pickle.py F +../../2.5.2/test/test_pkg.py . +../../2.5.2/test/test_pkgimport.py . +../../2.5.2/test/test_pow.py . +../../2.5.2/test/test_pprint.py . +../../2.5.2/test/test_profilehooks.py . +test_re.py F +test_repr.py F +../../2.5.2/test/test_richcmp.py . +test_scope.py . +test_set.py F +test_slice.py . +../../2.5.2/test/test_softspace.py . +test_sort.py F +../../2.5.2/test/test_str.py F +../../2.5.2/test/test_string.py F +../../2.5.2/test/test_StringIO.py . +../../2.5.2/test/test_syntax.py F +test_sys.py F +../../2.5.2/test/test_thread.py F +../../2.5.2/test/test_threaded_import.py F +../../2.5.2/test/test_threading.py F +../../2.5.2/test/test_threading_local.py F +../../2.5.2/test/test_time.py F +test_trace.py F +test_traceback.py F +../../2.5.2/test/test_transformer.py . +../../2.5.2/test/test_tuple.py F +../../2.5.2/test/test_types.py . +../../2.5.2/test/test_unary.py . +../../2.5.2/test/test_unicode.py F +../../2.5.2/test/test_unittest.py . +../../2.5.2/test/test_univnewlines.py f +test_unpack.py F +../../2.5.2/test/test_userdict.py . +../../2.5.2/test/test_userlist.py F +test_userstring.py F +../../2.5.2/test/test_warnings.py . +test_weakref.py F +test_xrange.py . -test_extcall - cannot be fixed. PyPy produces different TypeError messages but they are - also correct and useful (reviewed them again). +========================================================== 174 tests deselected by 'core' =========================================================== +===================================================== 65/120 passed + 0 skips in 459.34 seconds ===================================================== +=================================================================== failures: 55 ==================================================================== From pedronis at codespeak.net Tue Oct 7 15:50:20 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 7 Oct 2008 15:50:20 +0200 (CEST) Subject: [pypy-svn] r58753 - pypy/build/bot2/pypybuildbot Message-ID: <20081007135020.89845169E35@codespeak.net> Author: pedronis Date: Tue Oct 7 15:50:20 2008 New Revision: 58753 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: try with -O2 Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Tue Oct 7 15:50:20 2008 @@ -99,7 +99,7 @@ setup_steps(platform, self) - self.addStep(Translate(["-O0"], [])) + self.addStep(Translate(["-O2"], [])) self.addStep(shell.ShellCommand( description="lib-python test", From xoraxax at codespeak.net Tue Oct 7 15:56:55 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 15:56:55 +0200 (CEST) Subject: [pypy-svn] r58754 - in pypy/dist/pypy/translator: c/test tool tool/test Message-ID: <20081007135655.12B51169E90@codespeak.net> Author: xoraxax Date: Tue Oct 7 15:56:54 2008 New Revision: 58754 Modified: pypy/dist/pypy/translator/c/test/test_typed.py pypy/dist/pypy/translator/tool/staticsizereport.py pypy/dist/pypy/translator/tool/test/test_staticsizereport.py Log: (antocuni, xoraxax) Extend and fix the staticsizereport tests. Modified: pypy/dist/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_typed.py (original) +++ pypy/dist/pypy/translator/c/test/test_typed.py Tue Oct 7 15:56:54 2008 @@ -32,7 +32,7 @@ def compilefunc(self, t, func): from pypy.translator.c import genc - builder = genc.CExtModuleBuilder(t, func, config=t.config) + self.builder = builder = genc.CExtModuleBuilder(t, func, config=t.config) builder.generate_source() builder.compile() return builder.get_entry_point() Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Tue Oct 7 15:56:54 2008 @@ -91,7 +91,7 @@ def print_report_static_size(database, grouper=by_lltype): " Reports all objects with a specified grouper. " - _, report = report_static_size(database.globalcontainers(), grouper) + _, report = make_report_static_size(database.globalcontainers(), grouper) for line in report: print format_report_line(line) Modified: pypy/dist/pypy/translator/tool/test/test_staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/test/test_staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/test/test_staticsizereport.py Tue Oct 7 15:56:54 2008 @@ -1,5 +1,5 @@ from pypy.translator.c.test.test_typed import CompilationTestCase -from pypy.translator.tool.staticsizereport import group_static_size +from pypy.translator.tool.staticsizereport import group_static_size, guess_size class TestStaticSizeReport(CompilationTestCase): def test_simple(self): @@ -16,8 +16,24 @@ return a.key return a.next.key func = self.getcompiled(f, [int]) - size, num = group_static_size(self.builder.db) + size, num = group_static_size(self.builder.db, self.builder.db.globalcontainers()) for key, value in num.iteritems(): if "staticsizereport.A" in str(key) and "vtable" not in str(key): assert value == 101 + def test_large_dict(self): + d = {} + class wrap: + pass + for x in xrange(100): + i = wrap() + i.x = x + d[x] = i + def f(x): + return d[x].x + func = self.getcompiled(f, [int]) + gcontainers = self.builder.db.globalcontainers() + dictvalnode = [node for node in gcontainers if "struct dicttable" in repr(node.obj)][0] + assert guess_size(self.builder.db, dictvalnode, set()) > 100 + size, num = group_static_size(self.builder.db, gcontainers) + 1/0 From xoraxax at codespeak.net Tue Oct 7 16:00:05 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 16:00:05 +0200 (CEST) Subject: [pypy-svn] r58755 - in pypy/dist/pypy/translator/tool: . test Message-ID: <20081007140005.9575E169F25@codespeak.net> Author: xoraxax Date: Tue Oct 7 16:00:04 2008 New Revision: 58755 Modified: pypy/dist/pypy/translator/tool/staticsizereport.py pypy/dist/pypy/translator/tool/test/test_staticsizereport.py Log: Fixed code and test of staticsizereport. Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Tue Oct 7 16:00:04 2008 @@ -55,7 +55,6 @@ return 0 recursive.add(node) for dep in values_to_nodes(database, node.enum_dependencies()): - recursive.add(dep) size += guess_size(database, dep, recursive) return size Modified: pypy/dist/pypy/translator/tool/test/test_staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/test/test_staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/test/test_staticsizereport.py Tue Oct 7 16:00:04 2008 @@ -35,5 +35,4 @@ gcontainers = self.builder.db.globalcontainers() dictvalnode = [node for node in gcontainers if "struct dicttable" in repr(node.obj)][0] assert guess_size(self.builder.db, dictvalnode, set()) > 100 - size, num = group_static_size(self.builder.db, gcontainers) - 1/0 + #size, num = group_static_size(self.builder.db, gcontainers) From witulski at codespeak.net Tue Oct 7 16:05:45 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Tue, 7 Oct 2008 16:05:45 +0200 (CEST) Subject: [pypy-svn] r58756 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081007140545.0AC5C169ED5@codespeak.net> Author: witulski Date: Tue Oct 7 16:05:44 2008 New Revision: 58756 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: Allocation an register which is already in use works (allocate register changed) IDIV with IMM32 works Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Tue Oct 7 16:05:44 2008 @@ -161,7 +161,7 @@ """ tells the current position in memory""" raise NotImplementedError - + #TODO: support all combinations # The opcodes differs depending on the operands # Params: # W (64bit Operands), R (extends reg field), X (extend Index(SIB) field), B (extends r/m field, Base(SIB) field, opcode reg field), Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Tue Oct 7 16:05:44 2008 @@ -92,6 +92,7 @@ # "r14":None, # "r15":None, } + self.known_gv = [] for reg in used_registers: self.allocate_register(reg.reg) @@ -138,11 +139,17 @@ # IDIV RDX:RAX with QWREG # supports only RAX (64bit) with QWREG - def op_int_div(self, gv_x, gv_y): + def op_int_floordiv(self, gv_x, gv_y): gv_z = self.allocate_register("rax") + gv_w = self.allocate_register("rdx") self.mc.MOV(gv_z, gv_x) - self.mc.CDQ() #sign extention - self.mc.IDIV(gv_y) + self.mc.CDQ() #sign extention of rdx:rax + if isinstance(gv_y, Immediate32): + gv_u = self.allocate_register() + self.mc.MOV(gv_u,gv_y) + self.mc.IDIV(gv_u) + else: + self.mc.IDIV(gv_y) return gv_z # IDIV RDX:RAX with QWREG @@ -198,7 +205,7 @@ self.mc.SETGE(Register8("al")) return Register64("rax") - + # moves to pass arg. when making a jump to a block def _compute_moves(self, outputargs_gv, targetargs_gv): tar2src = {} tar2loc = {} @@ -217,16 +224,17 @@ #FIXME: can only jump 32bit #FIXME: imm8 insted of imm32? - def jump_if_true(self, gv_condition, args_for_jump_gv): - targetbuilder = Builder(args_for_jump_gv) - self.mc.CMP(gv_condition, Immediate32(0)) - self.mc.JNE(targetbuilder.mc.tell()) - # args_for_jump contain the registers which are used - # from the caller block. These registers cant be used by - # the targetbuilder - - #targetbuilder.come_from(self.mc, 'JNE') - return targetbuilder + def _new_jump(name, value): + from pypy.tool.sourcetools import func_with_new_name + def jump(self, gv_condition, args_for_jump_gv): + targetbuilder = Builder(args_for_jump_gv) + self.mc.CMP(gv_condition, Immediate32(value)) + self.mc.JNE(targetbuilder.mc.tell()) + return targetbuilder + return func_with_new_name(jump, name) + + jump_if_false = _new_jump("jump_if_false", 1) + jump_if_true = _new_jump('jump_if_true', 0) def finish_and_return(self, sigtoken, gv_returnvar): #self.mc.write("\xB8\x0F\x00\x00\x00") @@ -237,9 +245,8 @@ self._close() #FIXME: uses 32bit displ - #FIXME: neg. displacement??? # if the label is greater than 32bit - # it must be in a register + # it must be in a register (not supported) def finish_and_goto(self, outputargs_gv, target): #import pdb;pdb.set_trace() self._open() @@ -255,12 +262,30 @@ def allocate_register(self, register=None): if register is None: - return Register64(self.freeregisters.popitem()[0]) - else: if not self.freeregisters: raise NotImplementedError("spilling not implemented") + + new_gv = Register64(self.freeregisters.popitem()[0]) + self.known_gv.append(new_gv) + return new_gv + else: + if register not in self.freeregisters: + # the register must be in the list! + for i in range(len(self.known_gv)): + if register == self.known_gv[i].reg: + # move the values from the requiered register + # to an other one and return the + # requested one. + gv = self.allocate_register() + self.mc.MOV(gv,self.known_gv[i]) + new_gv = Register64(register) + self.known_gv.append(new_gv) + return new_gv + raise NotImplementedError("register moves") del self.freeregisters[register] - return Register64(register) + new_gv = Register64(register) + self.known_gv.append(new_gv) + return new_gv def end(self): pass Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Tue Oct 7 16:05:44 2008 @@ -100,14 +100,14 @@ builder.end() return gv_cmp -def make_mul_imm(rgenop, num): +def make_one_op_imm_instr(rgenop, instr_name, num): sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) - builder, gv_mul, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "mul") + builder, gv_op_imm, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "mul") builder.start_writing() - gv_result = builder.genop2("int_mul", gv_x, rgenop.genconst(num)) + gv_result = builder.genop2(instr_name, gv_x, rgenop.genconst(num)) builder.finish_and_return(sigtoken, gv_result) builder.end() - return gv_mul + return gv_op_imm class TestRGenopDirect(AbstractRGenOpTestsDirect): RGenOp = RX86_64GenOp @@ -148,15 +148,22 @@ def test_mul_imm32(self): rgenop = self.RGenOp() - mul_function = make_mul_imm(rgenop,200) + mul_function = make_one_op_imm_instr(rgenop, "int_mul", 200) fnptr = self.cast(mul_function,1) res = fnptr(210) assert res == 42000 - mul_function = make_mul_imm(rgenop,-9876) + mul_function = make_one_op_imm_instr(rgenop, "int_mul", -9876) fnptr = self.cast(mul_function,1) res = fnptr(12345) assert res == -121919220 + def test_idiv_imm32(self): + rgenop = self.RGenOp() + mul_function = make_one_op_imm_instr(rgenop, "int_floordiv", 7) + fnptr = self.cast(mul_function,1) + res = fnptr(77) + assert res == 11 + # Illegal instruction at mov(qwreg,imm64) #def test_mul_im64(self): @@ -188,7 +195,7 @@ #FIXME: ignores rdx and signs def test_idiv(self): - div_function = make_two_op_instr(self.RGenOp(), "int_div") + div_function = make_two_op_instr(self.RGenOp(), "int_floordiv") fnptr = self.cast(div_function,2) res = fnptr(100,3) assert res == 33 # integer div @@ -455,8 +462,6 @@ test_dummy_direct = skip test_largedummy_direct = skip test_branching_direct = skip - ##test_goto_direct = skip## - test_if_direct = skip test_switch_direct = skip test_large_switch_direct = skip test_fact_direct = skip From antocuni at codespeak.net Tue Oct 7 16:12:50 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 7 Oct 2008 16:12:50 +0200 (CEST) Subject: [pypy-svn] r58757 - in pypy/dist/pypy: annotation translator/goal Message-ID: <20081007141250.9A160169F05@codespeak.net> Author: antocuni Date: Tue Oct 7 16:12:48 2008 New Revision: 58757 Modified: pypy/dist/pypy/annotation/specialize.py pypy/dist/pypy/translator/goal/ann_override.py Log: (antocuni, xoraxax) add a "virtual" module name to these lambda functions, so that we can track them when generating statistics about static data Modified: pypy/dist/pypy/annotation/specialize.py ============================================================================== --- pypy/dist/pypy/annotation/specialize.py (original) +++ pypy/dist/pypy/annotation/specialize.py Tue Oct 7 16:12:48 2008 @@ -415,14 +415,14 @@ ## return funcdesc.cachedgraph(s1_type, alt_name='memo_%s' % funcdesc.name, ## builder=builder) -def make_constgraphbuilder(n, v=None, factory=None): +def make_constgraphbuilder(n, v=None, factory=None, srcmodule=None): def constgraphbuilder(translator, ignore): args = ','.join(["arg%d" % i for i in range(n)]) if factory is not None: computed_v = factory() else: computed_v = v - miniglobals = {'v': computed_v} + miniglobals = {'v': computed_v, '__name__': srcmodule} exec "constf = lambda %s: v" % args in miniglobals return translator.buildflowgraph(miniglobals['constf']) return constgraphbuilder Modified: pypy/dist/pypy/translator/goal/ann_override.py ============================================================================== --- pypy/dist/pypy/translator/goal/ann_override.py (original) +++ pypy/dist/pypy/translator/goal/ann_override.py Tue Oct 7 16:12:48 2008 @@ -65,7 +65,8 @@ return space.new_interned_str(x) else: return space.wrap(x) - builder = specialize.make_constgraphbuilder(2, factory=fold) + builder = specialize.make_constgraphbuilder(2, factory=fold, + srcmodule='') return funcdesc.cachedgraph((typ, x), builder=builder) return funcdesc.cachedgraph(typ) From cfbolz at codespeak.net Tue Oct 7 16:17:05 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 7 Oct 2008 16:17:05 +0200 (CEST) Subject: [pypy-svn] r58758 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081007141705.50908169F25@codespeak.net> Author: cfbolz Date: Tue Oct 7 16:17:02 2008 New Revision: 58758 Modified: pypy/branch/2.5-merge/pypy/objspace/std/setobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Log: (iko, cfbolz): KeyErrors should have the key. Modified: pypy/branch/2.5-merge/pypy/objspace/std/setobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/setobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/setobject.py Tue Oct 7 16:17:02 2008 @@ -444,23 +444,20 @@ try: del w_left.setdata[w_f] except KeyError: - raise OperationError(space.w_KeyError, - space.call_method(w_item,'__repr__')) + raise OperationError(space.w_KeyError, w_item) def set_remove__Set_settypedef(space, w_left, w_item): w_f = space.newfrozenset(make_setdata_from_w_iterable(space, w_item)) try: del w_left.setdata[w_f] except KeyError: - raise OperationError(space.w_KeyError, - space.call_method(w_item,'__repr__')) + raise OperationError(space.w_KeyError, w_item) def set_remove__Set_ANY(space, w_left, w_item): try: del w_left.setdata[w_item] except KeyError: - raise OperationError(space.w_KeyError, - space.call_method(w_item,'__repr__')) + raise OperationError(space.w_KeyError, w_item) def hash__Frozenset(space, w_set): multi = r_uint(1822399083) + r_uint(1822399083) + 1 Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Tue Oct 7 16:17:02 2008 @@ -83,3 +83,11 @@ s.add(A(s)) assert repr(s) == "set([1, 2, 3, set(...)])" + def test_keyerror_has_key(self): + s = set() + try: + s.remove(1) + except KeyError, e: + assert e.args[0] == 1 + else: + assert 0, "should raise" From xoraxax at codespeak.net Tue Oct 7 16:17:19 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 16:17:19 +0200 (CEST) Subject: [pypy-svn] r58759 - pypy/dist/pypy/objspace/std Message-ID: <20081007141719.44D71169F33@codespeak.net> Author: xoraxax Date: Tue Oct 7 16:17:18 2008 New Revision: 58759 Modified: pypy/dist/pypy/objspace/std/multimethod.py Log: Propagate __name__ in multimethods. Modified: pypy/dist/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/dist/pypy/objspace/std/multimethod.py (original) +++ pypy/dist/pypy/objspace/std/multimethod.py Tue Oct 7 16:17:18 2008 @@ -261,7 +261,7 @@ things_to_call): # support for inventing names for the entries in things_to_call # which are real function objects instead of strings - miniglobals = {'FailedToImplement': FailedToImplement} + miniglobals = {'FailedToImplement': FailedToImplement, '__name__': __name__} def invent_name(obj): if isinstance(obj, str): return obj From fijal at codespeak.net Tue Oct 7 16:18:28 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 7 Oct 2008 16:18:28 +0200 (CEST) Subject: [pypy-svn] r58760 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081007141828.38874169F39@codespeak.net> Author: fijal Date: Tue Oct 7 16:18:27 2008 New Revision: 58760 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_unpack.py Log: Fix doctests (well, I don't know what to put there) Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_unpack.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_unpack.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_unpack.py Tue Oct 7 16:18:27 2008 @@ -62,14 +62,14 @@ >>> a, b = t Traceback (most recent call last): ... - ValueError: too many values to unpack - + ValueError: Expected length 2, got 3 + Unpacking tuple of wrong size >>> a, b = l Traceback (most recent call last): ... - ValueError: too many values to unpack + ValueError: Expected length 2, got 3 Unpacking sequence too short From antocuni at codespeak.net Tue Oct 7 16:21:33 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 7 Oct 2008 16:21:33 +0200 (CEST) Subject: [pypy-svn] r58761 - pypy/dist/pypy/rpython Message-ID: <20081007142133.DEA71169E49@codespeak.net> Author: antocuni Date: Tue Oct 7 16:21:33 2008 New Revision: 58761 Modified: pypy/dist/pypy/rpython/extfunc.py Log: (antocuni, xoraxax) keep track of the module also here Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Tue Oct 7 16:21:33 2008 @@ -189,6 +189,7 @@ d = {'original_impl': impl, 's_result': s_result, 'fakeimpl': fakeimpl, + '__name__': __name__, } exec py.code.compile(""" from pypy.rlib.objectmodel import running_on_llinterp From xoraxax at codespeak.net Tue Oct 7 16:23:05 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 16:23:05 +0200 (CEST) Subject: [pypy-svn] r58762 - pypy/dist/pypy/translator/tool Message-ID: <20081007142305.3B331169E8E@codespeak.net> Author: xoraxax Date: Tue Oct 7 16:23:04 2008 New Revision: 58762 Modified: pypy/dist/pypy/translator/tool/staticsizereport.py Log: Add another helper function. Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Tue Oct 7 16:23:04 2008 @@ -7,7 +7,7 @@ def guess_module(graph): func = getattr(graph, 'func', None) - name = '' + name = None if func is not None: newname = func.func_globals.get('__name__', None) if newname is not None: @@ -95,6 +95,16 @@ print format_report_line(line) +def get_unknown_graphs(database): + funcnodes = [node for node in database.globalcontainers() + if node.nodekind == "func"] + for node in funcnodes: + graph = getattr(node.obj, 'graph', None) + if not graph: + continue + if not guess_module(graph): + yield graph + def print_aggregated_values_by_module_and_type(database, count_modules_separately=False): " Reports all objects by module and by lltype. " modules = {} @@ -106,7 +116,7 @@ graph = getattr(node.obj, 'graph', None) if not graph: continue - nodes_set = modules.setdefault(guess_module(graph), set()) + nodes_set = modules.setdefault(guess_module(graph) or '', set()) assert len(node.funcgens) == 1 nodes_set.update(values_to_nodes(database, node.funcgens[0].all_cached_consts)) modules = modules.items() From witulski at codespeak.net Tue Oct 7 16:39:14 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Tue, 7 Oct 2008 16:39:14 +0200 (CEST) Subject: [pypy-svn] r58763 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081007143914.129DC169EED@codespeak.net> Author: witulski Date: Tue Oct 7 16:39:13 2008 New Revision: 58763 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: added bool_not Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Tue Oct 7 16:39:13 2008 @@ -108,20 +108,27 @@ def genop2(self, opname, gv_arg1, gv_arg2): genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg1, gv_arg2) - + op_int_add = make_two_argument_method("ADD") op_int_and = make_two_argument_method("AND") - op_int_dec = make_one_argument_method("DEC") #for debuging - op_int_inc = make_one_argument_method("INC") #for debuging + op_int_dec = make_one_argument_method("DEC") #for debuging + op_int_inc = make_one_argument_method("INC") #for debuging op_int_mul = make_two_argument_method("IMUL") op_int_neg = make_one_argument_method("NEG") - op_int_not = make_one_argument_method("NOT") + op_int_not = make_one_argument_method("NOT") #for debuging op_int_or = make_two_argument_method("OR") op_int_push = make_one_argument_method("PUSH") #for debuging op_int_pop = make_one_argument_method("POP") #for debuging op_int_sub = make_two_argument_method("SUB") op_int_xor = make_two_argument_method("XOR") + def op_bool_not(self, gv_x): + gv_y = self.allocate_register() + self.mc.MOV(gv_y, Immediate32(1)) + self.mc.XOR(gv_x, gv_y) + return gv_x + + # FIXME: is that lshift val? # FIXME: uses rcx insted of cl def op_int_lshift(self, gv_x, gv_y): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Tue Oct 7 16:39:13 2008 @@ -461,23 +461,21 @@ test_float_loop_direct = skip test_dummy_direct = skip test_largedummy_direct = skip - test_branching_direct = skip test_switch_direct = skip test_large_switch_direct = skip test_fact_direct = skip test_calling_pause_direct = skip test_longwinded_and_direct = skip test_condition_result_cross_link_direct = skip - test_multiple_cmps = skip + test_multiple_cmps = skip## test_flipped_cmp_with_immediate = skip - test_tight_loop = skip test_jump_to_block_with_many_vars = skip test_same_as = skip test_pause_and_resume_direct = skip test_like_residual_red_call_with_exc_direct = skip test_call_functions_with_different_signatures_direct = skip test_defaultonly_switch = skip - test_bool_not_direct = skip + ## test_bool_not_direct = skip test_read_frame_var_direct = skip test_read_frame_var_float_direct = skip test_genconst_from_frame_var_direct = skip From cfbolz at codespeak.net Tue Oct 7 16:42:58 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 7 Oct 2008 16:42:58 +0200 (CEST) Subject: [pypy-svn] r58764 - pypy/branch/2.5-merge/pypy/objspace/std/test Message-ID: <20081007144258.113E5169F02@codespeak.net> Author: cfbolz Date: Tue Oct 7 16:42:57 2008 New Revision: 58764 Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Log: failing set test Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Tue Oct 7 16:42:57 2008 @@ -91,3 +91,17 @@ assert e.args[0] == 1 else: assert 0, "should raise" + + def test_subclass_with_hash(self): + # Bug #1257731 + class H(set): + def __hash__(self): + return int(id(self) & 0x7fffffff) + s = H() + f = set([s]) + print f + assert s in f + f.remove(s) + f.add(s) + f.discard(s) + From jlg at codespeak.net Tue Oct 7 16:51:24 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Tue, 7 Oct 2008 16:51:24 +0200 (CEST) Subject: [pypy-svn] r58765 - in pypy/branch/2.5-merge/pypy/module/operator: . test Message-ID: <20081007145124.42B5B169F39@codespeak.net> Author: jlg Date: Tue Oct 7 16:51:22 2008 New Revision: 58765 Modified: pypy/branch/2.5-merge/pypy/module/operator/app_operator.py pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Log: test and implementation of support for multiple gets in attrgetter() and itemgetter() Modified: pypy/branch/2.5-merge/pypy/module/operator/app_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/app_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/app_operator.py Tue Oct 7 16:51:22 2008 @@ -65,18 +65,31 @@ class attrgetter(object): - def __init__(self, name): - self.name = name + def __init__(self, attr, *args): + self.attrs = args + self.attr = attr def __call__(self, obj): - return getattr(obj, self.name) + result = getattr(obj, self.attr) + + if self.attrs: + list = [result] + [getattr(obj, attr) for attr in self.attrs] + return tuple(list) + + return result class itemgetter(object): - def __init__(self, index): - self.index = index + def __init__(self, item, *args): + self.items = args + self.item = item def __call__(self, obj): - return obj[self.index] + result = obj[self.item] + + if self.items: + list = [result] + [obj[item] for item in self.items] + return tuple(list) + + return result - Modified: pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Tue Oct 7 16:51:22 2008 @@ -15,3 +15,23 @@ assert a.get3("foobar") == "b" assert a.getx(*(a,)) == 5 assert a.get3(obj="foobar") == "b" + + + def test_getter_multiple_gest(self): + import operator + + class A(object): + pass + + a = A() + a.x = 'X' + a.y = 'Y' + a.z = 'Z' + + assert operator.attrgetter('x','z','y')(a) == ('X', 'Z', 'Y') + raises(TypeError, operator.attrgetter('x', (), 'y'), a) + + data = map(str, range(20)) + assert operator.itemgetter(2,10,5)(data) == ('2', '10', '5') + raises(TypeError, operator.itemgetter(2, 'x', 5), data) + From arigo at codespeak.net Tue Oct 7 16:56:46 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 16:56:46 +0200 (CEST) Subject: [pypy-svn] r58766 - in pypy/branch/2.5-merge/pypy/module/sys: . test Message-ID: <20081007145646.089A1169E8B@codespeak.net> Author: arigo Date: Tue Oct 7 16:56:46 2008 New Revision: 58766 Modified: pypy/branch/2.5-merge/pypy/module/sys/__init__.py pypy/branch/2.5-merge/pypy/module/sys/test/test_sysmodule.py pypy/branch/2.5-merge/pypy/module/sys/version.py Log: Implement sys.subversion. Modified: pypy/branch/2.5-merge/pypy/module/sys/__init__.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/sys/__init__.py (original) +++ pypy/branch/2.5-merge/pypy/module/sys/__init__.py Tue Oct 7 16:56:46 2008 @@ -55,6 +55,7 @@ 'version' : 'version.get_version(space)', 'pypy_version_info' : 'version.get_pypy_version_info(space)', 'pypy_svn_url' : 'version.get_svn_url(space)', + 'subversion' : 'version.get_subversion_info(space)', 'hexversion' : 'version.get_hexversion(space)', 'ps1' : 'space.wrap(">>>> ")', 'ps2' : 'space.wrap(".... ")', @@ -64,7 +65,6 @@ 'meta_path' : 'space.wrap([])', 'path_hooks' : 'space.wrap([])', 'path_importer_cache' : 'space.wrap({})', - #'subversion' : added in Python 2.5 'getdefaultencoding' : 'interp_encoding.getdefaultencoding', 'setdefaultencoding' : 'interp_encoding.setdefaultencoding', Modified: pypy/branch/2.5-merge/pypy/module/sys/test/test_sysmodule.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/sys/test/test_sysmodule.py (original) +++ pypy/branch/2.5-merge/pypy/module/sys/test/test_sysmodule.py Tue Oct 7 16:56:46 2008 @@ -377,3 +377,9 @@ def test_allattributes(self): sys.__dict__ # check that we don't crash initializing any attribute + + def test_subversion(self): + project, svnbranch, revision = sys.subversion + assert project == 'PyPy' + assert svnbranch == svnbranch.strip('/') + assert revision.isdigit() Modified: pypy/branch/2.5-merge/pypy/module/sys/version.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/sys/version.py (original) +++ pypy/branch/2.5-merge/pypy/module/sys/version.py Tue Oct 7 16:56:46 2008 @@ -10,6 +10,7 @@ PYPY_VERSION = (1, 0, 0, "alpha", '?') # the last item is replaced by the svn revision ^^^ +SVN_URL_HEAD = 'http://codespeak.net/svn/pypy/' SVN_URL = "$HeadURL$"[10:-28] REV = "$LastChangedRevision$"[22:-2] @@ -48,6 +49,13 @@ def get_svn_url(space): return space.wrap((SVN_URL, svn_revision())) +def get_subversion_info(space): + assert SVN_URL.startswith(SVN_URL_HEAD) + svnbranch = SVN_URL[len(SVN_URL_HEAD):].strip('/') + return space.newtuple([space.wrap('PyPy'), + space.wrap(svnbranch), + space.wrap(str(svn_revision()))]) + def tuple2hex(ver): d = {'alpha': 0xA, 'beta': 0xB, From arigo at codespeak.net Tue Oct 7 17:05:59 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 17:05:59 +0200 (CEST) Subject: [pypy-svn] r58767 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081007150559.65066169F01@codespeak.net> Author: arigo Date: Tue Oct 7 17:05:58 2008 New Revision: 58767 Removed: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_trace.py Log: The change done in this test doesn't really make sense. From jlg at codespeak.net Tue Oct 7 17:13:26 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Tue, 7 Oct 2008 17:13:26 +0200 (CEST) Subject: [pypy-svn] r58768 - in pypy/branch/2.5-merge/pypy/module/operator: . test Message-ID: <20081007151326.6EA38169E8E@codespeak.net> Author: jlg Date: Tue Oct 7 17:13:24 2008 New Revision: 58768 Modified: pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Log: concat supports only sequence types as arguments; contat test added Modified: pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py Tue Oct 7 17:13:24 2008 @@ -1,3 +1,5 @@ +from pypy.interpreter.error import OperationError + def index(space, w_a): return space.index(w_a) @@ -15,8 +17,11 @@ def concat(space, w_obj1, w_obj2): 'concat(a, b) -- Same as a a + b, for a and b sequences.' - return space.add(w_obj1, w_obj2) # XXX cPython only works on types with sequence api - # we support any with __add__ + if space.findattr(w_obj1, space.wrap('__getitem__')) is None or \ + space.findattr(w_obj2, space.wrap('__getitem__')) is None: + raise OperationError(space.w_TypeError, space.w_None) + + return space.add(w_obj1, w_obj2) def contains(space, w_obj1, w_obj2): 'contains(a, b) -- Same as b in a (note reversed operands).' Modified: pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Tue Oct 7 17:13:24 2008 @@ -35,3 +35,42 @@ assert operator.itemgetter(2,10,5)(data) == ('2', '10', '5') raises(TypeError, operator.itemgetter(2, 'x', 5), data) + def test_concat(self): + class Seq1: + def __init__(self, lst): + self.lst = lst + def __len__(self): + return len(self.lst) + def __getitem__(self, i): + return self.lst[i] + def __add__(self, other): + return self.lst + other.lst + def __mul__(self, other): + return self.lst * other + def __rmul__(self, other): + return other * self.lst + + class Seq2(object): + def __init__(self, lst): + self.lst = lst + def __len__(self): + return len(self.lst) + def __getitem__(self, i): + return self.lst[i] + def __add__(self, other): + return self.lst + other.lst + def __mul__(self, other): + return self.lst * other + def __rmul__(self, other): + return other * self.lst + + import operator + + raises(TypeError, operator.concat) + raises(TypeError, operator.concat, None, None) + assert operator.concat('py', 'thon') == 'python' + assert operator.concat([1, 2], [3, 4]) == [1, 2, 3, 4] + assert operator.concat(Seq1([5, 6]), Seq1([7])) == [5, 6, 7] + assert operator.concat(Seq2([5, 6]), Seq2([7])) == [5, 6, 7] + raises(TypeError, operator.concat, 13, 29) + From arigo at codespeak.net Tue Oct 7 17:20:31 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 17:20:31 +0200 (CEST) Subject: [pypy-svn] r58769 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081007152031.7EAD9169F5D@codespeak.net> Author: arigo Date: Tue Oct 7 17:20:28 2008 New Revision: 58769 Added: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py - copied, changed from r58763, pypy/branch/2.5-merge/lib-python/2.5.2/test/test_support.py Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py Log: Add a proposed extension to test_support to make PyPy-specific extensions a bit more official. Try to use it in test_itertools.py. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py Tue Oct 7 17:20:28 2008 @@ -195,11 +195,10 @@ zip('abc', 'def')) self.assertEqual([pair for pair in izip('abc', 'def')], zip('abc', 'def')) - # the following test deals with a specific implementation detail, - # that izip "reuses" the SAME tuple object each time when it can; - # it does not apply correctly to pypy, so I'm commenting it -- AM - # ids = map(id, izip('abc', 'def')) - # self.assertEqual(min(ids), max(ids)) + if test_support.check_impl_detail: + # izip "reuses" the same tuple object each time when it can + ids = map(id, izip('abc', 'def')) + self.assertEqual(min(ids), max(ids)) ids = map(id, list(izip('abc', 'def'))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) @@ -364,11 +363,9 @@ self.assertRaises(TypeError, tee, [1,2], 3, 'x') # tee object should be instantiable - # XXX why?? the following test would pass too if type(a)('def') - # just returned iter('abc')... - #a, b = tee('abc') - #c = type(a)('def') - #self.assertEqual(list(c), list('def')) + 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(xrange(2000), 3) @@ -394,20 +391,19 @@ self.assert_(a is c) # test tee_new - # XXX the same "why??" as above - #t1, t2 = tee('abc') - #tnew = type(t1) - #self.assertRaises(TypeError, tnew) - #self.assertRaises(TypeError, tnew, 10) - #t3 = tnew(t1) - #self.assert_(list(t1) == list(t2) == list(t3) == list('abc')) + t1, t2 = tee('abc') + tnew = type(t1) + self.assertRaises(TypeError, tnew) + self.assertRaises(TypeError, tnew, 10) + t3 = tnew(t1) + self.assert_(list(t1) == list(t2) == list(t3) == list('abc')) # test that tee objects are weak referencable a, b = tee(xrange(10)) p = proxy(a) self.assertEqual(getattr(p, '__class__'), type(b)) del a - import gc; gc.collect(); gc.collect(); gc.collect() + test_support.gc_collect() self.assertRaises(ReferenceError, getattr, p, '__class__') def test_StopIteration(self): Copied: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py (from r58763, pypy/branch/2.5-merge/lib-python/2.5.2/test/test_support.py) ============================================================================== --- pypy/branch/2.5-merge/lib-python/2.5.2/test/test_support.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py Tue Oct 7 17:20:28 2008 @@ -525,3 +525,38 @@ break except: break + +#======================================================================= +# distinguishing between language-level tests and implementation details + +# Use the following flag to guard CPython's implementation-specific tests. +check_impl_detail = (hasattr(sys, 'subversion') and + sys.subversion[0] == 'CPython') + +def impl_detail(f): + """A decorator to skip a whole function if not running on top of CPython. + """ + if check_impl_details: + return f + else: + def _skip_check_impl_detail(*args, **kwds): + if verbose: + sys.stderr.write("Skipping %s because of memory " + "constraint\n" % (f.__name__,)) + return + return skip_check_impl_detail + +def gc_collect(): + """Force as many objects as possible to be collected. + + In non-CPython implementations of Python, this is needed because + timely deallocation is not guaranteed by the garbage collector. + (Even in CPython this can be the case in case of reference cycles.) + This means that __del__ methods may be called later than expected + and weakrefs may remain alive for longer than expected. This + function tries its best to force all garbage objects to disappear. + """ + import gc + gc.collect() + gc.collect() + gc.collect() From xoraxax at codespeak.net Tue Oct 7 17:24:17 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 17:24:17 +0200 (CEST) Subject: [pypy-svn] r58770 - in pypy/dist/pypy: objspace/std translator/tool Message-ID: <20081007152417.2726A169F5D@codespeak.net> Author: xoraxax Date: Tue Oct 7 17:24:16 2008 New Revision: 58770 Modified: pypy/dist/pypy/objspace/std/multimethod.py pypy/dist/pypy/translator/tool/staticsizereport.py Log: Propagate module name, fix the unknown grpahs functions. Modified: pypy/dist/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/dist/pypy/objspace/std/multimethod.py (original) +++ pypy/dist/pypy/objspace/std/multimethod.py Tue Oct 7 17:24:16 2008 @@ -932,6 +932,7 @@ from pypy.rlib.jit import hint miniglobals['hint'] = hint + miniglobals['__name__'] = __name__ entry = FuncEntry(bodylines, miniglobals, fallback) key = entry.key() try: Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Tue Oct 7 17:24:16 2008 @@ -96,11 +96,10 @@ def get_unknown_graphs(database): - funcnodes = [node for node in database.globalcontainers() - if node.nodekind == "func"] + funcnodes = [node for node in database.globalcontainers() if node.nodekind == "func"] for node in funcnodes: graph = getattr(node.obj, 'graph', None) - if not graph: + if not graph or not getattr(graph, 'func', None): continue if not guess_module(graph): yield graph From antocuni at codespeak.net Tue Oct 7 17:26:01 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 7 Oct 2008 17:26:01 +0200 (CEST) Subject: [pypy-svn] r58771 - pypy/dist/pypy/translator/goal Message-ID: <20081007152601.37929169F5D@codespeak.net> Author: antocuni Date: Tue Oct 7 17:26:00 2008 New Revision: 58771 Modified: pypy/dist/pypy/translator/goal/ann_override.py Log: (antocuni, xoraxax) track the module name also here Modified: pypy/dist/pypy/translator/goal/ann_override.py ============================================================================== --- pypy/dist/pypy/translator/goal/ann_override.py (original) +++ pypy/dist/pypy/translator/goal/ann_override.py Tue Oct 7 17:26:00 2008 @@ -121,7 +121,7 @@ def builder(translator, func): #print "LOOKUP", attr pol.consider_lookup(funcdesc.bookkeeper, attr) - d = {} + d = {'__name__': ''} exec CACHED_LOOKUP % {'attr': attr} in d return translator.buildflowgraph(d['lookup_'+attr]) return funcdesc.cachedgraph(attr, builder=builder) @@ -136,7 +136,7 @@ def builder(translator, func): #print "LOOKUP_IN_TYPE_WHERE", attr pol.consider_lookup_in_type_where(funcdesc.bookkeeper, attr) - d = {} + d = {'__name__': ''} exec CACHED_LOOKUP_IN_TYPE_WHERE % {'attr': attr} in d return translator.buildflowgraph(d['lookup_in_type_where_'+attr]) return funcdesc.cachedgraph(attr, builder=builder) From jlg at codespeak.net Tue Oct 7 17:27:20 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Tue, 7 Oct 2008 17:27:20 +0200 (CEST) Subject: [pypy-svn] r58772 - in pypy/branch/2.5-merge/pypy/module/operator: . test Message-ID: <20081007152720.852391684FA@codespeak.net> Author: jlg Date: Tue Oct 7 17:27:20 2008 New Revision: 58772 Modified: pypy/branch/2.5-merge/pypy/module/operator/app_operator.py pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Log: concat supports only sequence types as arguments; contat test added Modified: pypy/branch/2.5-merge/pypy/module/operator/app_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/app_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/app_operator.py Tue Oct 7 17:27:20 2008 @@ -54,8 +54,11 @@ 'repeat(a, b) -- Return a * b, where a is a sequence, and b is an integer.' if not isinstance(num, (int, long)): raise TypeError, 'an integer is required' - return obj * num # XXX cPython only supports objects with the sequence - # protocol. We support any with a __mul__ + if not isSequenceType(obj): + raise TypeError, "non-sequence object can't be repeated" + + return obj * num + __repeat__ = repeat def setslice(a, b, c, d): Modified: pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Tue Oct 7 17:27:20 2008 @@ -74,3 +74,56 @@ assert operator.concat(Seq2([5, 6]), Seq2([7])) == [5, 6, 7] raises(TypeError, operator.concat, 13, 29) + def test_repeat(self): + class Seq1: + def __init__(self, lst): + self.lst = lst + def __len__(self): + return len(self.lst) + def __getitem__(self, i): + return self.lst[i] + def __add__(self, other): + return self.lst + other.lst + def __mul__(self, other): + return self.lst * other + def __rmul__(self, other): + return other * self.lst + + class Seq2(object): + def __init__(self, lst): + self.lst = lst + def __len__(self): + return len(self.lst) + def __getitem__(self, i): + return self.lst[i] + def __add__(self, other): + return self.lst + other.lst + def __mul__(self, other): + return self.lst * other + def __rmul__(self, other): + return other * self.lst + + a = range(3) + raises(TypeError, operator.repeat) + raises(TypeError, operator.repeat, a, None) + assert operator.repeat(a, 2) == a+a + assert operator.repeat(a, 1) == a + assert operator.repeat(a, 0) == [] + a = (1, 2, 3) + assert operator.repeat(a, 2) == a+a + assert operator.repeat(a, 1) == a + assert operator.repeat(a, 0) == () + a = '123' + assert operator.repeat(a, 2) == a+a + assert operator.repeat(a, 1) == a + assert operator.repeat(a, 0) == '' + a = Seq1([4, 5, 6]) + assert operator.repeat(a, 2) == [4, 5, 6, 4, 5, 6] + assert operator.repeat(a, 1) == [4, 5, 6] + assert operator.repeat(a, 0) == [] + a = Seq2([4, 5, 6]) + assert operator.repeat(a, 2) == [4, 5, 6, 4, 5, 6] + assert operator.repeat(a, 1) == [4, 5, 6] + assert operator.repeat(a, 0) == [] + raises(TypeError, operator.repeat, 6, 7 + From jlg at codespeak.net Tue Oct 7 17:33:51 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Tue, 7 Oct 2008 17:33:51 +0200 (CEST) Subject: [pypy-svn] r58773 - pypy/branch/2.5-merge/pypy/module/operator/test Message-ID: <20081007153351.91B9D169E8D@codespeak.net> Author: jlg Date: Tue Oct 7 17:33:51 2008 New Revision: 58773 Modified: pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Log: repeat() supports only sequence types Modified: pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Tue Oct 7 17:33:51 2008 @@ -103,6 +103,8 @@ def __rmul__(self, other): return other * self.lst + import operator + a = range(3) raises(TypeError, operator.repeat) raises(TypeError, operator.repeat, a, None) @@ -125,5 +127,5 @@ assert operator.repeat(a, 2) == [4, 5, 6, 4, 5, 6] assert operator.repeat(a, 1) == [4, 5, 6] assert operator.repeat(a, 0) == [] - raises(TypeError, operator.repeat, 6, 7 + raises(TypeError, operator.repeat, 6, 7) From arigo at codespeak.net Tue Oct 7 17:38:48 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 17:38:48 +0200 (CEST) Subject: [pypy-svn] r58774 - pypy/branch/2.5-merge/pypy/module/sys Message-ID: <20081007153848.7EA0E169ED5@codespeak.net> Author: arigo Date: Tue Oct 7 17:38:48 2008 New Revision: 58774 Modified: pypy/branch/2.5-merge/pypy/module/sys/version.py Log: Oups! Fix this. It crashes with https or svn+ssh checkouts. Modified: pypy/branch/2.5-merge/pypy/module/sys/version.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/sys/version.py (original) +++ pypy/branch/2.5-merge/pypy/module/sys/version.py Tue Oct 7 17:38:48 2008 @@ -10,7 +10,7 @@ PYPY_VERSION = (1, 0, 0, "alpha", '?') # the last item is replaced by the svn revision ^^^ -SVN_URL_HEAD = 'http://codespeak.net/svn/pypy/' +TRIM_URL_UP_TO = 'svn/pypy/' SVN_URL = "$HeadURL$"[10:-28] REV = "$LastChangedRevision$"[22:-2] @@ -50,8 +50,10 @@ return space.wrap((SVN_URL, svn_revision())) def get_subversion_info(space): - assert SVN_URL.startswith(SVN_URL_HEAD) - svnbranch = SVN_URL[len(SVN_URL_HEAD):].strip('/') + svnbranch = SVN_URL + if TRIM_URL_UP_TO in svnbranch: + svnbranch = svnbranch.split(TRIM_URL_UP_TO, 1)[1] + svnbranch = svnbranch.strip('/') return space.newtuple([space.wrap('PyPy'), space.wrap(svnbranch), space.wrap(str(svn_revision()))]) From jlg at codespeak.net Tue Oct 7 17:45:06 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Tue, 7 Oct 2008 17:45:06 +0200 (CEST) Subject: [pypy-svn] r58776 - in pypy/branch/2.5-merge/pypy/module/operator: . test Message-ID: <20081007154506.5E3D5169E3E@codespeak.net> Author: jlg Date: Tue Oct 7 17:45:05 2008 New Revision: 58776 Modified: pypy/branch/2.5-merge/pypy/module/operator/app_operator.py pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Log: isSequenceType() returns False with mapping type Modified: pypy/branch/2.5-merge/pypy/module/operator/app_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/app_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/app_operator.py Tue Oct 7 17:45:05 2008 @@ -48,7 +48,7 @@ def isSequenceType(obj,): 'isSequenceType(a) -- Return True if a has a sequence type, False otherwise.' - return hasattr(obj, '__getitem__') + return hasattr(obj, '__getitem__') and not hasattr(obj, 'keys') def repeat(obj, num): 'repeat(a, b) -- Return a * b, where a is a sequence, and b is an integer.' Modified: pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Tue Oct 7 17:45:05 2008 @@ -129,3 +129,15 @@ assert operator.repeat(a, 0) == [] raises(TypeError, operator.repeat, 6, 7) + def test_isSequenceType(self): + import operator + + raises(TypeError, operator.isSequenceType) + assert operator.isSequenceType(dir()) + assert operator.isSequenceType(()) + assert operator.isSequenceType(xrange(10)) + assert operator.isSequenceType('yeahbuddy') + assert not operator.isSequenceType(3) + class Dict(dict): pass + assert not operator.isSequenceType(Dict()) + From arigo at codespeak.net Tue Oct 7 17:57:07 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 17:57:07 +0200 (CEST) Subject: [pypy-svn] r58777 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081007155707.B4899169F60@codespeak.net> Author: arigo Date: Tue Oct 7 17:57:05 2008 New Revision: 58777 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py Log: Argue why this is nonsense. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_itertools.py Tue Oct 7 17:57:05 2008 @@ -363,9 +363,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 test_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(xrange(2000), 3) From arigo at codespeak.net Tue Oct 7 18:00:53 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 18:00:53 +0200 (CEST) Subject: [pypy-svn] r58778 - in pypy/branch/2.5-merge/pypy/module/itertools: . test Message-ID: <20081007160053.375B01684BF@codespeak.net> Author: arigo Date: Tue Oct 7 18:00:52 2008 New Revision: 58778 Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Log: Test and implement *half* of the semantics of _tee.__new__(). Modified: pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/interp_itertools.py Tue Oct 7 18:00:52 2008 @@ -723,8 +723,21 @@ finally: self.index += 1 +def W_TeeIterable___new__(space, w_subtype, w_iterable): + # Obscure and undocumented function. PyPy only supports w_iterable + # being a W_TeeIterable, because the case where it is a general + # iterable is useless and confusing as far as I can tell (as the + # semantics are then slightly different; see the XXX in lib-python's + # test_itertools). + myiter = space.interp_w(W_TeeIterable, w_iterable) + tee_state = myiter.tee_state + return space.wrap(W_TeeIterable(space, tee_state)) + W_TeeIterable.typedef = TypeDef( '_tee', + __new__ = interp2app(W_TeeIterable___new__, unwrap_spec=[ObjSpace, + W_Root, + W_Root]), __iter__ = interp2app(W_TeeIterable.iter_w, unwrap_spec=['self']), next = interp2app(W_TeeIterable.next_w, unwrap_spec=['self']), __weakref__ = make_weakref_descr(W_TeeIterable), Modified: pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py (original) +++ pypy/branch/2.5-merge/pypy/module/itertools/test/test_itertools.py Tue Oct 7 18:00:52 2008 @@ -455,6 +455,21 @@ res = list(d) assert res == list('foobar') + def test_tee_instantiate(self): + import itertools + + a, b = itertools.tee(iter('foobar')) + c = type(a)(a) + assert a is not b + assert a is not c + assert b is not c + res = list(a) + assert res == list('foobar') + res = list(b) + assert res == list('foobar') + res = list(c) + assert res == list('foobar') + def test_groupby(self): import itertools From iko at codespeak.net Tue Oct 7 18:01:06 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Tue, 7 Oct 2008 18:01:06 +0200 (CEST) Subject: [pypy-svn] r58779 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081007160106.0B178169E4B@codespeak.net> Author: iko Date: Tue Oct 7 18:01:04 2008 New Revision: 58779 Modified: pypy/branch/2.5-merge/pypy/objspace/std/setobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Log: (iko, cfbolz) Fix set autoconversion to frozenset Modified: pypy/branch/2.5-merge/pypy/objspace/std/setobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/setobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/setobject.py Tue Oct 7 18:01:04 2008 @@ -113,6 +113,12 @@ if w_iterable is not None: w_obj.setdata.update(make_setdata_from_w_iterable(space, w_iterable)) +def _convert_set_to_frozenset(space, w_obj): + if space.is_true(space.isinstance(w_obj, space.w_set)): + return space.newfrozenset(make_setdata_from_w_iterable(space, w_obj)) + else: + return None + # helper functions for set operation on dicts def _is_frozenset_exact(w_obj): @@ -303,25 +309,18 @@ ne__Frozenset_ANY = ne__Set_ANY -def contains__Set_Set(space, w_left, w_other): - # optimization only (for the case __Set_settypedef) - w_f = space.newfrozenset(w_other.setdata) - return space.newbool(w_f in w_left.setdata) - -contains__Frozenset_Set = contains__Set_Set - -def contains__Set_settypedef(space, w_left, w_other): - # This is the general case to handle 'set in set' or 'set in - # frozenset'. We need this in case w_other is of type 'set' but the - # case 'contains__Set_Set' is not selected by the multimethod logic, - # which can occur (see test_builtinshortcut). - w_f = space.newfrozenset(make_setdata_from_w_iterable(space, w_other)) - return space.newbool(w_f in w_left.setdata) - -contains__Frozenset_settypedef = contains__Set_settypedef - def contains__Set_ANY(space, w_left, w_other): - return space.newbool(w_other in w_left.setdata) + try: + return space.newbool(w_other in w_left.setdata) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + + w_f = _convert_set_to_frozenset(space, w_other) + if w_f is not None: + return space.newbool(w_f in w_left.setdata) + else: + return space.w_False contains__Frozenset_ANY = contains__Set_ANY @@ -422,42 +421,43 @@ gt__Frozenset_Set = gt__Set_Set gt__Frozenset_Frozenset = gt__Set_Set +def _discard_from_set(space, w_left, w_item): + """ + Discard an element from a set, with automatic conversion to + frozenset if the argument is a set. -def set_discard__Set_Set(space, w_left, w_item): - # optimization only (the general case is set_discard__Set_settypedef) - w_f = space.newfrozenset(w_item.setdata) - if w_f in w_left.setdata: - del w_left.setdata[w_f] - -def set_discard__Set_settypedef(space, w_left, w_item): - w_f = space.newfrozenset(make_setdata_from_w_iterable(space, w_item)) - if w_f in w_left.setdata: - del w_left.setdata[w_f] - -def set_discard__Set_ANY(space, w_left, w_item): - if w_item in w_left.setdata: - del w_left.setdata[w_item] - -def set_remove__Set_Set(space, w_left, w_item): - # optimization only (the general case is set_remove__Set_settypedef) - w_f = space.newfrozenset(w_item.setdata) + Returns None if successfully removed, otherwise the object that + wasn't there is returned. + """ try: - del w_left.setdata[w_f] + del w_left.setdata[w_item] + return None except KeyError: - raise OperationError(space.w_KeyError, w_item) - -def set_remove__Set_settypedef(space, w_left, w_item): - w_f = space.newfrozenset(make_setdata_from_w_iterable(space, w_item)) + return w_item + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + + w_f = _convert_set_to_frozenset(space, w_item) + if w_f is None: + return w_item try: del w_left.setdata[w_f] + return None except KeyError: - raise OperationError(space.w_KeyError, w_item) + return w_f + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + return w_f + +def set_discard__Set_ANY(space, w_left, w_item): + _discard_from_set(space, w_left, w_item) def set_remove__Set_ANY(space, w_left, w_item): - try: - del w_left.setdata[w_item] - except KeyError: - raise OperationError(space.w_KeyError, w_item) + w_f = _discard_from_set(space, w_left, w_item) + if w_f is not None: + raise OperationError(space.w_KeyError, w_f) def hash__Frozenset(space, w_set): multi = r_uint(1822399083) + r_uint(1822399083) + 1 Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Tue Oct 7 18:01:04 2008 @@ -105,3 +105,41 @@ f.add(s) f.discard(s) + def test_autoconvert_to_frozen__contains(self): + s = set([frozenset([1,2])]) + + assert set([1,2]) in s + + def test_autoconvert_to_frozen_remove(self): + s = set([frozenset([1,2])]) + + s.remove(set([1,2])) + assert len(s) == 0 + raises(KeyError, s.remove, set([1,2])) + + def test_autoconvert_to_frozen_discard(self): + s = set([frozenset([1,2])]) + + s.discard(set([1,2])) + assert len(s) == 0 + s.discard(set([1,2])) + + def test_autoconvert_to_frozen_onlyon_type_error(self): + class A(set): + def __hash__(self): + return id(self) + + s = A([1, 2, 3]) + s2 = set([2, 3, s]) + assert A() not in s2 + s2.add(frozenset()) + assert A() not in s2 + raises(KeyError, s2.remove, A()) + + def test_autoconvert_key_error(self): + s = set([frozenset([1, 2]), frozenset([3, 4])]) + try: + s.remove(set([2, 3])) + except KeyError, e: + assert isinstance(e.args[0], frozenset) + assert e.args[0] == frozenset([2, 3]) From arigo at codespeak.net Tue Oct 7 18:08:16 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 18:08:16 +0200 (CEST) Subject: [pypy-svn] r58780 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081007160816.342D2169EAF@codespeak.net> Author: arigo Date: Tue Oct 7 18:08:15 2008 New Revision: 58780 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py Log: Fix the skip message (which was copy-pasted from a few pages earlier in the same file). Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py Tue Oct 7 18:08:15 2008 @@ -541,8 +541,8 @@ else: def _skip_check_impl_detail(*args, **kwds): if verbose: - sys.stderr.write("Skipping %s because of memory " - "constraint\n" % (f.__name__,)) + sys.stderr.write("Skipping %s checking CPython-specific " + "implementation details\n" % (f.__name__,)) return return skip_check_impl_detail From witulski at codespeak.net Tue Oct 7 18:13:49 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Tue, 7 Oct 2008 18:13:49 +0200 (CEST) Subject: [pypy-svn] r58781 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081007161349.CB52A169F5F@codespeak.net> Author: witulski Date: Tue Oct 7 18:13:47 2008 New Revision: 58781 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: fixed the alternate encoding bug (wrong opcodes where written to memory) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Tue Oct 7 18:13:47 2008 @@ -127,7 +127,7 @@ new_opcode = hex(int(opcode,16)+modrm1) assert len(new_opcode[2:len(new_opcode)]) == 2 self.write_rex_byte(rexW, rexR, rexX, rexB) - self.write(new_opcode[2:len(new_opcode)]) + self.write(chr(int(new_opcode[2:len(new_opcode)],16))) self.writeImm64(arg2.value) return quadreg_instr @@ -148,7 +148,7 @@ new_opcode = hex(int(opcode,16)+modrm1) assert len(new_opcode[2:len(new_opcode)]) == 2 self.write_rex_byte(rexW, rexR, rexX, rexB) - self.write(new_opcode[2:len(new_opcode)]) + self.write(chr(int(new_opcode[2:len(new_opcode)],16))) return quadreg_instr class X86_64CodeBuilder(object): @@ -221,6 +221,7 @@ _SUB_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x29", 3, None, None) _SUB_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, 0, "\x81", 3, None, 5) + _XOR_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, None, "\x81", 3, None, 6) _XOR_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x31", 3, None, None) # TODO: maybe a problem with more ore less than two arg. Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Tue Oct 7 18:13:47 2008 @@ -122,12 +122,16 @@ op_int_sub = make_two_argument_method("SUB") op_int_xor = make_two_argument_method("XOR") + # TODO: support reg8 + def op_cast_bool_to_int(self, gv_x): + assert isinstance(gv_x, Register64) + return gv_x + + # 0 xor 1 == 1 + # 1 xor 1 == 0 def op_bool_not(self, gv_x): - gv_y = self.allocate_register() - self.mc.MOV(gv_y, Immediate32(1)) - self.mc.XOR(gv_x, gv_y) - return gv_x - + self.mc.XOR(gv_x, Immediate32(1)) + return gv_x # FIXME: is that lshift val? # FIXME: uses rcx insted of cl @@ -151,7 +155,7 @@ gv_w = self.allocate_register("rdx") self.mc.MOV(gv_z, gv_x) self.mc.CDQ() #sign extention of rdx:rax - if isinstance(gv_y, Immediate32): + if isinstance(gv_y, Immediate32): #support imm32 gv_u = self.allocate_register() self.mc.MOV(gv_u,gv_y) self.mc.IDIV(gv_u) @@ -212,7 +216,7 @@ self.mc.SETGE(Register8("al")) return Register64("rax") - # moves to pass arg. when making a jump to a block + # the moves to pass arg. when making a jump to a block def _compute_moves(self, outputargs_gv, targetargs_gv): tar2src = {} tar2loc = {} @@ -337,8 +341,8 @@ builder = Builder() # TODO: Builder._open() entrypoint = builder.mc.tell() - # TODO: support more than two reg - register_list = ["rdi","rsi"] + # from http://www.x86-64.org/documentation/abi.pdf + register_list = ["rdi","rsi","rdx","rcx","r8","r9"] # fill the list with the correct registers inputargs_gv = [builder.allocate_register(register_list[i]) for i in range(len(arg_tokens))] Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Tue Oct 7 18:13:47 2008 @@ -102,7 +102,7 @@ def make_one_op_imm_instr(rgenop, instr_name, num): sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) - builder, gv_op_imm, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "mul") + builder, gv_op_imm, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "one_op_imm_instr") builder.start_writing() gv_result = builder.genop2(instr_name, gv_x, rgenop.genconst(num)) builder.finish_and_return(sigtoken, gv_result) @@ -166,12 +166,12 @@ # Illegal instruction at mov(qwreg,imm64) - #def test_mul_im64(self): - # rgenop = self.RGenOp() - # mul_function = make_mul_imm(rgenop,int("123456789",16)) - # fnptr = self.cast(mul_function,1) - # res = fnptr(2) - # assert res == int("123456789",16)*2 + def test_mul_imm64(self): + rgenop = self.RGenOp() + mul_function = make_one_op_imm_instr(rgenop, "int_mul", int("123456789",16)) + fnptr = self.cast(mul_function,1) + res = fnptr(2) + assert res == int("123456789",16)*2 def test_imul(self): mul_function = make_two_op_instr(self.RGenOp(), "int_mul") @@ -467,7 +467,7 @@ test_calling_pause_direct = skip test_longwinded_and_direct = skip test_condition_result_cross_link_direct = skip - test_multiple_cmps = skip## + test_multiple_cmps = skip test_flipped_cmp_with_immediate = skip test_jump_to_block_with_many_vars = skip test_same_as = skip @@ -475,7 +475,6 @@ test_like_residual_red_call_with_exc_direct = skip test_call_functions_with_different_signatures_direct = skip test_defaultonly_switch = skip - ## test_bool_not_direct = skip test_read_frame_var_direct = skip test_read_frame_var_float_direct = skip test_genconst_from_frame_var_direct = skip From arigo at codespeak.net Tue Oct 7 18:17:03 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 18:17:03 +0200 (CEST) Subject: [pypy-svn] r58782 - pypy/branch/2.5-merge/lib-python Message-ID: <20081007161703.3CEA0169F5B@codespeak.net> Author: arigo Date: Tue Oct 7 18:17:01 2008 New Revision: 58782 Modified: pypy/branch/2.5-merge/lib-python/conftest.py Log: Add logic to detect RegrTest entries that no longer correspond to existing test files. Remove 2 such entries. Modified: pypy/branch/2.5-merge/lib-python/conftest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/conftest.py (original) +++ pypy/branch/2.5-merge/lib-python/conftest.py Tue Oct 7 18:17:01 2008 @@ -65,6 +65,7 @@ self._usemodules = usemodules.split() self._compiler = compiler self.core = core + assert self.getfspath().check(), "%r not found!" % (basename,) def usemodules(self): return self._usemodules #+ pypy_option.usemodules @@ -371,7 +372,6 @@ RegrTest('test_re.py', enabled=True, core=True), - RegrTest('test_regex.py', enabled=False), RegrTest('test_repr.py', enabled=True, core=True), #rev 10840: 6 of 12 tests fail. Always minor stuff like #'' != '' @@ -452,7 +452,6 @@ RegrTest('test_timeout.py', enabled=False), #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser - RegrTest('test_timing.py', enabled=False, dumbtest=1), RegrTest('test_tokenize.py', enabled=False), RegrTest('test_trace.py', enabled=True, core=True), RegrTest('test_traceback.py', enabled=True, core=True), From arigo at codespeak.net Tue Oct 7 18:29:25 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 18:29:25 +0200 (CEST) Subject: [pypy-svn] r58783 - pypy/branch/2.5-merge/lib-python Message-ID: <20081007162925.3842A169F89@codespeak.net> Author: arigo Date: Tue Oct 7 18:29:24 2008 New Revision: 58783 Modified: pypy/branch/2.5-merge/lib-python/conftest.py Log: * Check for missing RegrTest() declarations. * Add the missing ones for 2.5.2 Modified: pypy/branch/2.5-merge/lib-python/conftest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/conftest.py (original) +++ pypy/branch/2.5-merge/lib-python/conftest.py Tue Oct 7 18:29:24 2008 @@ -500,8 +500,55 @@ RegrTest('test_zipfile.py', enabled=False, dumbtest=1), RegrTest('test_zipimport.py', enabled=True, usemodules='zlib zipimport'), RegrTest('test_zlib.py', enabled=True, usemodules='zlib'), + + # new test files from 2.5 + RegrTest('test_ast.py', enabled=True), + RegrTest('test_bigaddrspace.py', enabled=True), + RegrTest('test_bigmem.py', enabled=True), + RegrTest('test_cProfile.py', enabled=True), + RegrTest('test_cmd_line.py', enabled=True), + RegrTest('test_code.py', enabled=True), + RegrTest('test_coding.py', enabled=True), + RegrTest('test_complex_args.py', enabled=True), + RegrTest('test_contextlib.py', enabled=True), + RegrTest('test_ctypes.py', enabled=True), + RegrTest('test_defaultdict.py', enabled=True), + RegrTest('test_email_renamed.py', enabled=True), + RegrTest('test_exception_variations.py', enabled=True), + RegrTest('test_float.py', enabled=True), + RegrTest('test_functools.py', enabled=True), + RegrTest('test_index.py', enabled=True), + RegrTest('test_old_mailbox.py', enabled=True), + RegrTest('test_pep352.py', enabled=True), + RegrTest('test_platform.py', enabled=True), + RegrTest('test_runpy.py', enabled=True), + RegrTest('test_sqlite.py', enabled=True), + RegrTest('test_startfile.py', enabled=True), + RegrTest('test_structmembers.py', enabled=True), + RegrTest('test_urllib2_localnet.py', enabled=True), + RegrTest('test_uuid.py', enabled=True), + RegrTest('test_wait3.py', enabled=True), + RegrTest('test_wait4.py', enabled=True), + RegrTest('test_with.py', enabled=True), + RegrTest('test_wsgiref.py', enabled=True), + RegrTest('test_xdrlib.py', enabled=True), + RegrTest('test_xml_etree.py', enabled=True), + RegrTest('test_xml_etree_c.py', enabled=True), + RegrTest('test_zipfile64.py', enabled=True), ] +def check_testmap_complete(): + listed_names = dict.fromkeys([regrtest.basename for regrtest in testmap]) + listed_names['test_support.py'] = True # ignore this + missing = [] + for path in regrtestdir.listdir(fil='test_*.py'): + name = path.basename + if name not in listed_names: + missing.append(' RegrTest(%r, enabled=True),' % (name,)) + missing.sort() + assert not missing, "non-listed tests:\n%s" % ('\n'.join(missing),) +check_testmap_complete() + class RegrDirectory(py.test.collect.Directory): """ The central hub for gathering CPython's compliance tests Basically we work off the above 'testmap' From xoraxax at codespeak.net Tue Oct 7 18:51:01 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 18:51:01 +0200 (CEST) Subject: [pypy-svn] r58784 - pypy/dist/pypy/translator/tool Message-ID: <20081007165101.71CB5169E4D@codespeak.net> Author: xoraxax Date: Tue Oct 7 18:51:00 2008 New Revision: 58784 Modified: pypy/dist/pypy/translator/tool/staticsizereport.py Log: Add non-verbose reporting to staticsizereport. Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Tue Oct 7 18:51:00 2008 @@ -104,7 +104,7 @@ if not guess_module(graph): yield graph -def print_aggregated_values_by_module_and_type(database, count_modules_separately=False): +def print_aggregated_values_by_module_and_type(database, count_modules_separately=False, verbose=False): " Reports all objects by module and by lltype. " modules = {} reports = [] @@ -140,8 +140,11 @@ for size, modulename, report in reports: if not size: continue - print "########### %i %s ####################################" % (size, modulename) - for line in report: - print " " * 4 + format_report_line(line) - print + if verbose: + print "########### %i %s ####################################" % (size, modulename) + for line in report: + print " " * 4 + format_report_line(line) + print + else: + print "%i\%s" % (size, modulename) From xoraxax at codespeak.net Tue Oct 7 18:52:44 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 7 Oct 2008 18:52:44 +0200 (CEST) Subject: [pypy-svn] r58785 - pypy/dist/pypy/translator/goal Message-ID: <20081007165244.31A41169EE6@codespeak.net> Author: xoraxax Date: Tue Oct 7 18:52:43 2008 New Revision: 58785 Modified: pypy/dist/pypy/translator/goal/ann_override.py Log: Avoid SystemErrors in the translation. Modified: pypy/dist/pypy/translator/goal/ann_override.py ============================================================================== --- pypy/dist/pypy/translator/goal/ann_override.py (original) +++ pypy/dist/pypy/translator/goal/ann_override.py Tue Oct 7 18:52:43 2008 @@ -121,7 +121,7 @@ def builder(translator, func): #print "LOOKUP", attr pol.consider_lookup(funcdesc.bookkeeper, attr) - d = {'__name__': ''} + d = {'__name__': ''} exec CACHED_LOOKUP % {'attr': attr} in d return translator.buildflowgraph(d['lookup_'+attr]) return funcdesc.cachedgraph(attr, builder=builder) @@ -136,7 +136,7 @@ def builder(translator, func): #print "LOOKUP_IN_TYPE_WHERE", attr pol.consider_lookup_in_type_where(funcdesc.bookkeeper, attr) - d = {'__name__': ''} + d = {'__name__': ''} exec CACHED_LOOKUP_IN_TYPE_WHERE % {'attr': attr} in d return translator.buildflowgraph(d['lookup_in_type_where_'+attr]) return funcdesc.cachedgraph(attr, builder=builder) From arigo at codespeak.net Tue Oct 7 19:19:37 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 7 Oct 2008 19:19:37 +0200 (CEST) Subject: [pypy-svn] r58786 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081007171937.85B2A169EF6@codespeak.net> Author: arigo Date: Tue Oct 7 19:19:34 2008 New Revision: 58786 Modified: pypy/branch/2.5-merge/pypy/objspace/std/objecttype.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_obj.py Log: Test and fix for a corner case shown by a CPython test. Modified: pypy/branch/2.5-merge/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/objecttype.py Tue Oct 7 19:19:34 2008 @@ -69,6 +69,12 @@ def descr__init__(space, w_obj, __args__): pass +def descr__reduce__(space, w_obj, proto=0): + if proto >= 2: + return reduce_2(space, w_obj) + w_proto = space.wrap(proto) + return reduce_1(space, w_obj, w_proto) + def descr__reduce_ex__(space, w_obj, proto=0): w_st_reduce = space.wrap('__reduce__') w_reduce = space.findattr(w_obj, w_st_reduce) @@ -79,14 +85,11 @@ w_objtype = space.w_object w_obj_dict = space.getattr(w_objtype, space.wrap('__dict__')) w_obj_reduce = space.getitem(w_obj_dict, w_st_reduce) - override = space.is_true(space.ne(w_cls_reduce, w_obj_reduce)) + override = not space.is_w(w_cls_reduce, w_obj_reduce) # print 'OVR', override, w_cls_reduce, w_obj_reduce if override: return space.call(w_reduce, space.newtuple([])) - if proto >= 2: - return reduce_2(space, w_obj) - w_proto = space.wrap(proto) - return reduce_1(space, w_obj, w_proto) + return descr__reduce__(space, w_obj, proto) app = gateway.applevel(r''' def reduce_1(obj, proto): @@ -174,7 +177,7 @@ __hash__ = gateway.interp2app(default_identity_hash), __reduce_ex__ = gateway.interp2app(descr__reduce_ex__, unwrap_spec=[gateway.ObjSpace,gateway.W_Root,int]), - __reduce__ = gateway.interp2app(descr__reduce_ex__, + __reduce__ = gateway.interp2app(descr__reduce__, unwrap_spec=[gateway.ObjSpace,gateway.W_Root,int]), __init__ = gateway.interp2app(descr__init__, unwrap_spec=[gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_obj.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_obj.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_obj.py Tue Oct 7 19:19:34 2008 @@ -25,3 +25,10 @@ x = X() assert (hash(x) & sys.maxint) == (id(x) & sys.maxint) assert hash(x) == object.__hash__(x) + + def test_reduce_recursion_bug(self): + class X(object): + def __reduce__(self): + return object.__reduce__(self) + (':-)',) + s = X().__reduce__() + assert s[-1] == ':-)' From jlg at codespeak.net Tue Oct 7 19:23:24 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Tue, 7 Oct 2008 19:23:24 +0200 (CEST) Subject: [pypy-svn] r58787 - in pypy/branch/2.5-merge/pypy/module/operator: . test Message-ID: <20081007172324.875C7169EF6@codespeak.net> Author: jlg Date: Tue Oct 7 19:23:23 2008 New Revision: 58787 Modified: pypy/branch/2.5-merge/pypy/module/operator/__init__.py pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Log: in-place functions added, CPython test_operator passes Modified: pypy/branch/2.5-merge/pypy/module/operator/__init__.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/__init__.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/__init__.py Tue Oct 7 19:23:23 2008 @@ -34,7 +34,11 @@ 'le', 'lshift', 'lt', 'mod', 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', 'setitem', 'sequenceIncludes', - 'sub', 'truediv', 'truth', 'xor'] + 'sub', 'truediv', 'truth', 'xor', + 'iadd', 'iand', 'iconcat', 'idiv', 'ifloordiv', + 'ilshift', 'imod', 'imul', 'ior', 'ipow', 'irepeat', + 'irshift', 'isub', 'itruediv', 'ixor'] + interpleveldefs = {} for name in interp_names: @@ -72,4 +76,21 @@ '__sub__' : 'sub', '__truediv__' : 'truediv', '__xor__' : 'xor', + # in-place + '__iadd__' : 'iadd', + '__iand__' : 'iand', + '__iconcat__' : 'iconcat', + '__idiv__' : 'idiv', + '__ifloordiv__' : 'ifloordiv', + '__ilshift__' : 'ilshift', + '__imod__' : 'imod', + '__imul__' : 'imul', + '__ior__' : 'ior', + '__ipow__' : 'ipow', + '__irepeat__' : 'irepeat', + '__irshift__' : 'irshift', + '__isub__' : 'isub', + '__itruediv__' : 'itruediv', + '__ixor__' : 'ixor', } + Modified: pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py Tue Oct 7 19:23:23 2008 @@ -8,15 +8,15 @@ return space.abs(w_obj) def add(space, w_obj1, w_obj2): - 'add(a, b) -- Same as a a + b' + 'add(a, b) -- Same as a + b' return space.add(w_obj1, w_obj2) def and_(space, w_obj1, w_obj2): - 'and_(a, b) -- Same as a a & b' + 'and_(a, b) -- Same as a & b' return space.and_(w_obj1, w_obj2) def concat(space, w_obj1, w_obj2): - 'concat(a, b) -- Same as a a + b, for a and b sequences.' + 'concat(a, b) -- Same as a + b, for a and b sequences.' if space.findattr(w_obj1, space.wrap('__getitem__')) is None or \ space.findattr(w_obj2, space.wrap('__getitem__')) is None: raise OperationError(space.w_TypeError, space.w_None) @@ -162,3 +162,73 @@ def xor(space, w_a, w_b): 'xor(a, b) -- Same as a ^ b.' return space.xor(w_a, w_b) + +# in-place operations + +def iadd(space, w_obj1, w_obj2): + 'iadd(a, b) -- Same as a += b.' + return space.inplace_add(w_obj1, w_obj2) + +def iand(space, w_obj1, w_obj2): + 'iand(a, b) -- Same as a =& b' + return space.inplace_and(w_obj1, w_obj2) + +def idiv(space, w_a, w_b): + 'idiv(a, b) -- Same as a /= b when __future__.division is no in effect' + return space.inplace_div(w_a, w_b) + +def ifloordiv(space, w_a, w_b): + 'ifloordiv(a, b) -- Same as a //= b.' + return space.inplace_floordiv(w_a, w_b) + +def ilshift(space, w_a, w_b): + 'ilshift(a, b) -- Same as a <<= b.' + return space.inplace_lshift(w_a, w_b) + +def imod(space, w_a, w_b): + 'imod(a, b) -- Same as a %= b.' + return space.inplace_mod(w_a, w_b) + +def imul(space, w_a, w_b): + 'imul(a, b) -- Same as a *= b.' + return space.inplace_mul(w_a, w_b) + +def ior(space, w_a, w_b): + 'ior(a, b) -- Same as a |= b.' + return space.inplace_or(w_a, w_b) + +def ipow(space, w_a, w_b): + 'ipow(a, b) -- Same as a **= b.' + return space.inplace_pow(w_a, w_b) + +def irshift(space, w_a, w_b): + 'irshift(a, b) -- Same as a >>= b.' + return space.inplace_rshift(w_a, w_b) + +def isub(space, w_a, w_b): + 'isub(a, b) -- Same as a -= b.' + return space.inplace_sub(w_a, w_b) + +def itruediv(space, w_a, w_b): + 'itruediv(a, b) -- Same as a /= b when __future__.division is in effect.' + return space.inplace_truediv(w_a, w_b) + +def ixor(space, w_a, w_b): + 'ixor(a, b) -- Same as a ^= b.' + return space.inplace_xor(w_a, w_b) + +def iconcat(space, w_obj1, w_obj2): + 'iconcat(a, b) -- Same as a += b, for a and b sequences.' + if space.findattr(w_obj1, space.wrap('__getitem__')) is None or \ + space.findattr(w_obj2, space.wrap('__getitem__')) is None: + raise OperationError(space.w_TypeError, space.w_None) + + return space.inplace_add(w_obj1, w_obj2) + +def irepeat(space, w_obj1, w_obj2): + 'irepeat(a, b) -- Same as a *= b, for a and b sequences.' + if space.findattr(w_obj1, space.wrap('__getitem__')) is None: + raise OperationError(space.w_TypeError, space.w_None) + + return space.inplace_mul(w_obj1, w_obj2) + Modified: pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Tue Oct 7 19:23:23 2008 @@ -141,3 +141,14 @@ class Dict(dict): pass assert not operator.isSequenceType(Dict()) + def test_inplace(self): + import operator + + list = [] + assert operator.iadd(list, [1, 2]) is list + assert list == [1, 2] + + list = [1, 2] + assert operator.imul(list, 2) is list + assert list == [1, 2, 1, 2] + From hpk at codespeak.net Tue Oct 7 19:40:44 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 7 Oct 2008 19:40:44 +0200 (CEST) Subject: [pypy-svn] r58788 - in pypy/build/bot2: . codespeak-html pypybuildbot Message-ID: <20081007174044.C978A168454@codespeak.net> Author: hpk Date: Tue Oct 7 19:40:44 2008 New Revision: 58788 Added: pypy/build/bot2/codespeak-html/ - copied from r58782, pypy/build/bot2/wyvern-html/ Modified: pypy/build/bot2/codespeak-html/index.html pypy/build/bot2/master.cfg pypy/build/bot2/pypybuildbot/builds.py pypy/build/bot2/pypybuildbot/master.py Log: (pedronis,hpk) * run 2.5-merge branch by default for now * run pypy's own tests nightly and translation+lib-python tests nightly * have wyvern and cobra as build slaves for starters Modified: pypy/build/bot2/codespeak-html/index.html ============================================================================== --- pypy/build/bot2/wyvern-html/index.html (original) +++ pypy/build/bot2/codespeak-html/index.html Tue Oct 7 19:40:44 2008 @@ -6,7 +6,7 @@ -

Welcome to Wyvern's PyPy Buildbot!

+

Welcome to codespeak's PyPy Buildbot!

  • the Summary Display will give you a Modified: pypy/build/bot2/master.cfg ============================================================================== --- pypy/build/bot2/master.cfg (original) +++ pypy/build/bot2/master.cfg Tue Oct 7 19:40:44 2008 @@ -12,7 +12,7 @@ execfile(os.path.expanduser('~/bot2/pypybuildbot/master.py')) -if socket.gethostname() != "wyvern": # for debugging +if socket.gethostname() not in ("wyvern", "code0.codespeak.net"): # for debugging for builderdict in BuildmasterConfig['builders']: builderdict["slavenames"] = ['localhost'] BuildmasterConfig['buildbotURL'] = "http://localhost:%d/" % (httpPortNumber) Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Tue Oct 7 19:40:44 2008 @@ -70,7 +70,7 @@ "-p.buildbot-sourcedata", "."], )) factory.addStep(source.SVN(baseURL="http://codespeak.net/svn/pypy/", - defaultBranch="dist")) + defaultBranch="branch/2.5-merge")) class PyPyOwnTestFactory(factory.BuildFactory): Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Tue Oct 7 19:40:44 2008 @@ -31,9 +31,9 @@ 'slavePortnum': slavePortnum, 'change_source': [], - 'schedulers': [Nightly("nightly", - ["own-linux-x86-32"], - hour=4, minute=45)], + 'schedulers': [ + Nightly("nightly", ["own-linux-x86-32", "pypy-c-lib-python-linux-x86-32"], hour=4, minute=45), + ], 'status': [status], 'slaves': [BuildSlave(name, password) @@ -42,19 +42,19 @@ 'builders': [ {"name": "own-linux-x86-32", - "slavenames": ["wyvern"], + "slavenames": ["wyvern", "cobra"], "builddir": "own-linux-x86-32", "factory": pypyOwnTestFactory }, {"name": "pypy-c-lib-python-linux-x86-32", - "slavenames": ["wyvern"], + "slavenames": ["wyvern", "cobra"], "builddir": "pypy-c-lib-python-linux-x86-32", "factory": pypyTranslatedLibPythonTestFactory }, ], - 'buildbotURL': 'http://wyvern.cs.uni-duesseldorf.de:%d/'%(httpPortNumber), + 'buildbotURL': 'http://codespeak.net:%d/'%(httpPortNumber), 'projectURL': 'http://codespeak.net/pypy/', 'projectName': 'PyPy'} From hpk at codespeak.net Tue Oct 7 21:21:30 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 7 Oct 2008 21:21:30 +0200 (CEST) Subject: [pypy-svn] r58789 - pypy/dist/pypy/lib/distributed/test Message-ID: <20081007192130.38A75169E23@codespeak.net> Author: hpk Date: Tue Oct 7 21:21:27 2008 New Revision: 58789 Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py pypy/dist/pypy/lib/distributed/test/test_socklayer.py Log: try to import pygreen, otherwise skip. Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py ============================================================================== --- pypy/dist/pypy/lib/distributed/test/test_greensock.py (original) +++ pypy/dist/pypy/lib/distributed/test/test_greensock.py Tue Oct 7 21:21:27 2008 @@ -2,6 +2,9 @@ import py from pypy.conftest import gettestobjspace, option +def setup_module(mod): + py.test.importorskip("pygreen") # found e.g. in py/trunk/contrib + class AppTestDistributedGreensock(object): def setup_class(cls): if not option.runappdirect: @@ -41,7 +44,7 @@ def test_remote_call(self): from distributed import socklayer import sys - from py.__.green.greenexecnet import PopenGateway + from pygreen.greenexecnet import PopenGateway gw = PopenGateway() rp = socklayer.spawn_remote_side(self.remote_side_code, gw) a = rp.get_remote("a") @@ -49,8 +52,8 @@ def test_remote_counting(self): from distributed import socklayer - from py.__.green.greensock2 import allof - from py.__.green.greenexecnet import PopenGateway + from pygreen.greensock2 import allof + from pygreen.greenexecnet import PopenGateway gws = [PopenGateway() for i in range(3)] rps = [socklayer.spawn_remote_side(self.remote_side_code, gw) for gw in gws] Modified: pypy/dist/pypy/lib/distributed/test/test_socklayer.py ============================================================================== --- pypy/dist/pypy/lib/distributed/test/test_socklayer.py (original) +++ pypy/dist/pypy/lib/distributed/test/test_socklayer.py Tue Oct 7 21:21:27 2008 @@ -1,6 +1,9 @@ - +import py from pypy.conftest import gettestobjspace +def setup_module(mod): + py.test.importorskip("pygreen") # found e.g. in py/trunk/contrib + # XXX think how to close the socket class AppTestSocklayer: @@ -18,9 +21,9 @@ import py except ImportError: skip("pylib not importable") - from py.__.green.pipe.gsocket import GreenSocket + from pygreen.pipe.gsocke import GreenSocket from distributed.socklayer import socket_loop, connect - from py.__.green.greensock2 import oneof, allof + from pygreen.greensock2 import oneof, allof def one(): socket_loop(('127.0.0.1', 21211), {'x':x}, socket=GreenSocket) From hpk at codespeak.net Wed Oct 8 10:22:08 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 8 Oct 2008 10:22:08 +0200 (CEST) Subject: [pypy-svn] r58791 - pypy/branch/2.5-merge/lib-python Message-ID: <20081008082208.584CC169F54@codespeak.net> Author: hpk Date: Wed Oct 8 10:22:05 2008 New Revision: 58791 Modified: pypy/branch/2.5-merge/lib-python/conftest.py Log: don't do any setup for running regression tests Modified: pypy/branch/2.5-merge/lib-python/conftest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/conftest.py (original) +++ pypy/branch/2.5-merge/lib-python/conftest.py Wed Oct 8 10:22:05 2008 @@ -67,6 +67,11 @@ self.core = core assert self.getfspath().check(), "%r not found!" % (basename,) + def setup(self): + pass + def teardown(self): + pass + def usemodules(self): return self._usemodules #+ pypy_option.usemodules usemodules = property(usemodules) From cfbolz at codespeak.net Wed Oct 8 11:06:04 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 8 Oct 2008 11:06:04 +0200 (CEST) Subject: [pypy-svn] r58792 - pypy/extradoc/sprintinfo/october-2008 Message-ID: <20081008090604.76FC9169F88@codespeak.net> Author: cfbolz Date: Wed Oct 8 11:06:04 2008 New Revision: 58792 Modified: pypy/extradoc/sprintinfo/october-2008/planning.txt Log: (all): planning for today Modified: pypy/extradoc/sprintinfo/october-2008/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/october-2008/planning.txt (original) +++ pypy/extradoc/sprintinfo/october-2008/planning.txt Wed Oct 8 11:06:04 2008 @@ -15,43 +15,50 @@ Tasks: - - improve the 64-bit JIT backend PROGRESS (John, ...) + - improve the 64-bit JIT backend MORE PROGRESS (John, ...) + loops are working now - merge the pypy-pytrunk branch DONE: merged and removed - run translation and the CPython tests through buildbot on pypy-c - SOME PROGRESS (Samuele, Holger) + BASICALLY DONE: buildmaster on codespeak now - - get access to bigdog's Windows machine and set up a buildbot slave + - cleanup wyvern (Samuele) - - look at the TODO list of the buildbot stuff + - ask bigdog to add his machines - - merge the 2.5 branch (Iko, Armin, Maciek, Jakub, Carl Friedrich) - - fix module bugs: BASICALLY DONE - - update stdlib to 2.5.2 - - run more CPython tests + - add a py.test -A builder - - windows buildbot slave + - look at the TODO list of the buildbot stuff + - merge the 2.5 branch (Maciek, Jakub) + - fix pypy/module bugs: BASICALLY DONE + - update stdlib to 2.5.2 DONE + - fix more CPython tests IN-PROGRESS + - finish set stuff (Iko, Carl Friedrich) - - looking at the static data of pypy-c IN-PROGRESS (Alexander, Anto) - - use shared dicts for oldstyle classes DONE - + - looking at the static data of pypy-c BASICALLY DONE, integration needed + (Alexander, Anto) + - malloc-removal-directed inlining to reduce the code size NEW APPROACH NEEDED - measuring memory behaviour - run memory-benchmarks nightly? - - merge gc-experiments branch? + - merge gc-experiments branch (Carl Friedrich, Maciek) - builtin-profiling branch needs to be merged - - py-lib needs some fixes about pdb + - py-lib needs some fixes about pdb DONE + + + - setting up a scratchbox environment (Alexander, Holger) + - measuring startup behaviour (Alexander, Holger) Discussion Tasks: From pedronis at codespeak.net Wed Oct 8 11:28:21 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 11:28:21 +0200 (CEST) Subject: [pypy-svn] r58793 - pypy/dist/pypy/doc Message-ID: <20081008092821.7A75B169F85@codespeak.net> Author: pedronis Date: Wed Oct 8 11:28:18 2008 New Revision: 58793 Modified: pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/index.txt Log: point to codespeak buildbot master Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Wed Oct 8 11:28:18 2008 @@ -105,7 +105,7 @@ subset of them at a time.** To run them all daily we have a BuildBot based setup, a summary of its results can be seen at: - http://wyvern.cs.uni-duesseldorf.de:8099/summary + http://codespeak.net:8099/summary .. _`if PyPy works on your machine/platform`: index.html#status .. _`autotest driver`: http://codespeak.net/pipermail/pypy-dev/2006q3/003273.html Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Wed Oct 8 11:28:18 2008 @@ -178,7 +178,7 @@ .. _`bytecode interpreter`: interpreter.html .. _`EU reports`: index-report.html .. _`Technical reports`: index-report.html -.. _`summary`: http://wyvern.cs.uni-duesseldorf.de:8099/summary +.. _`summary`: http://codespeak.net:8099/summary .. _`ideas for PyPy related projects`: project-ideas.html .. _`Nightly builds and benchmarks`: http://tuatara.cs.uni-duesseldorf.de/benchmark.html .. _`directory reference`: From pedronis at codespeak.net Wed Oct 8 11:32:39 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 11:32:39 +0200 (CEST) Subject: [pypy-svn] r58794 - in pypy/build/bot2: . wyvern-html Message-ID: <20081008093239.0764F169EED@codespeak.net> Author: pedronis Date: Wed Oct 8 11:32:39 2008 New Revision: 58794 Removed: pypy/build/bot2/wyvern-html/ Modified: pypy/build/bot2/master.cfg Log: wyvern is not a master anymore Modified: pypy/build/bot2/master.cfg ============================================================================== --- pypy/build/bot2/master.cfg (original) +++ pypy/build/bot2/master.cfg Wed Oct 8 11:32:39 2008 @@ -12,7 +12,7 @@ execfile(os.path.expanduser('~/bot2/pypybuildbot/master.py')) -if socket.gethostname() not in ("wyvern", "code0.codespeak.net"): # for debugging +if socket.gethostname() not in ("code0.codespeak.net",): # for debugging for builderdict in BuildmasterConfig['builders']: builderdict["slavenames"] = ['localhost'] BuildmasterConfig['buildbotURL'] = "http://localhost:%d/" % (httpPortNumber) From arigo at codespeak.net Wed Oct 8 11:36:08 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 11:36:08 +0200 (CEST) Subject: [pypy-svn] r58795 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081008093608.C3937169F81@codespeak.net> Author: arigo Date: Wed Oct 8 11:36:08 2008 New Revision: 58795 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Change the data model to account for aliasing. Very much work in progress. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Wed Oct 8 11:36:08 2008 @@ -8,6 +8,113 @@ # ____________________________________________________________ +class MallocTypeDesc(object): + + def __init__(self, MALLOCTYPE): + self.MALLOCTYPE = MALLOCTYPE + self.names_and_types = [] + self.name2index = {} + self.initialize_type(MALLOCTYPE) + self.immutable_struct = MALLOCTYPE._hints.get('immutable') + + def initialize_type(self, TYPE): + fieldnames = TYPE._names + firstname, FIRSTTYPE = TYPE._first_struct() + if FIRSTTYPE is not None: + self.initialize_type(FIRSTTYPE) + fieldnames = fieldnames[1:] + for name in fieldnames: + FIELDTYPE = TYPE._flds[name] + self.name2index[name] = len(self.names_and_types) + self.names_and_types.append((name, FIELDTYPE)) + + +class SpecNode(object): + pass + + +class RuntimeSpecNode(SpecNode): + + def getfrozenkey(self, memo): + return 'R' + + def find_rt_nodes(self, memo, result): + result.append(self) + + def copy(self, function, name, TYPE, memo): + return function(name, TYPE) + + def contains_mutable(self): + return False + + +class VirtualSpecNode(SpecNode): + + def __init__(self, typedesc, fields): + self.typedesc = typedesc + self.fields = fields # list of SpecNodes + + def getfrozenkey(self, memo): + if self in memo: + return memo[self] + else: + memo[self] = len(memo) + result = [self.typedesc] + for subnode in self.fields: + result.append(subnode.getfrozenkey(memo)) + return tuple(result) + + def find_rt_nodes(self, memo, result): + if self in memo: + return + memo[self] = True + for subnode in self.fields: + subnode.find_rt_nodes(memo, result) + + def copy(self, function, _name, _TYPE, memo): + if self in memo: + return memo[self] + newnode = VirtualSpecNode(self.typedesc, []) + memo[self] = newnode + for (name, FIELDTYPE), subnode in zip(self.typedesc.names_and_types, + self.fields): + newsubnode = subnode.copy(function, name, FIELDTYPE, memo) + newnode.fields.append(newsubnode) + return newnode + + def contains_mutable(self): + if not self.typedesc.immutable_struct: + return True + for subnode in self.fields: + if subnode.contains_mutable(): + return True + return False + + +def getfrozenkey(nodelist): + memo = {} + return tuple([node.getfrozenkey(memo) for node in nodelist]) + +def find_rt_nodes(nodelist): + result = [] + memo = {} + for node in nodelist: + node.find_rt_nodes(memo, result) + return result + +def is_trivial_nodelist(nodelist): + for node in nodelist: + if not isinstance(node, RuntimeSpecNode): + return False + return True + +def contains_mutable(nodelist): + for node in nodelist: + if node.contains_mutable(): + return True + return False + + class CannotVirtualize(Exception): pass @@ -18,6 +125,7 @@ self.graphs = graphs self.new_graphs = {} self.cache = BlockSpecCache() + self.malloctypedescs = {} self.count_virtualized = 0 def report_result(self): @@ -50,7 +158,12 @@ return progress def try_remove_malloc(self, block, op): - mallocspec = MallocSpecializer(self, op.result.concretetype.TO) + MALLOCTYPE = op.result.concretetype.TO + try: + dsc = self.malloctypedescs[MALLOCTYPE] + except KeyError: + dsc = self.malloctypedescs[MALLOCTYPE] = MallocTypeDesc(MALLOCTYPE) + mallocspec = MallocSpecializer(self, dsc) mallocspec.remove_malloc(block, op.result) mallocspec.propagate_specializations() # if we read this point without a CannotVirtualize, success @@ -67,14 +180,14 @@ class BlockSpecCache(object): def __init__(self, fallback=None): - self.specialized_blocks = {} - self.block_keys = {} - self.graph_starting_at = {} + self.specialized_blocks = {} # {(org Block, frozenkey): spec Block} + self.graph_starting_at = {} # {spec Block: spec Graph} self.fallback = fallback - def lookup_spec_block(self, block, extra_key): - key = self.block_keys.get(block, frozenset()) - key = key.union([extra_key]) + def lookup_spec_block(self, orgblock, nodelist): + if is_trivial_nodelist(nodelist): + return orgblock + key = orgblock, getfrozenkey(nodelist) try: return self.specialized_blocks[key] except KeyError: @@ -83,11 +196,10 @@ else: return self.fallback.specialized_blocks.get(key) - def remember_spec_block(self, block, extra_key, specblock): - key = self.block_keys.get(block, frozenset()) - key = key.union([extra_key]) + def remember_spec_block(self, orgblock, nodelist, specblock): + assert len(nodelist) == len(orgblock.inputargs) + key = orgblock, getfrozenkey(nodelist) self.specialized_blocks[key] = specblock - self.block_keys[specblock] = key def lookup_graph_starting_at(self, startblock): try: @@ -103,69 +215,56 @@ def push_changes(self): self.fallback.specialized_blocks.update(self.specialized_blocks) - self.fallback.block_keys.update(self.block_keys) self.fallback.graph_starting_at.update(self.graph_starting_at) class MallocSpecializer(object): - def __init__(self, mallocv, MALLOCTYPE): + def __init__(self, mallocv, malloctypedesc): self.mallocv = mallocv - self.MALLOCTYPE = MALLOCTYPE - self.names_and_types = [] - self.name2index = {} - self.initialize_type(MALLOCTYPE) - self.immutable_struct = MALLOCTYPE._hints.get('immutable') + self.malloctypedesc = malloctypedesc self.pending_specializations = [] self.cache = BlockSpecCache(fallback=mallocv.cache) - def initialize_type(self, TYPE): - fieldnames = TYPE._names - firstname, FIRSTTYPE = TYPE._first_struct() - if FIRSTTYPE is not None: - self.initialize_type(FIRSTTYPE) - fieldnames = fieldnames[1:] - for name in fieldnames: - FIELDTYPE = TYPE._flds[name] - self.name2index[name] = len(self.names_and_types) - self.names_and_types.append((name, FIELDTYPE)) - def remove_malloc(self, block, v_result): self.startblock = block spec = BlockSpecializer(self, v_result) - spec.initialize_renamings(block.inputargs) + trivialnodelist = [RuntimeSpecNode() for v in block.inputargs] + spec.initialize_renamings(block.inputargs, trivialnodelist) self.newinputargs = spec.expand_vars(block.inputargs) self.newoperations = spec.specialize_operations(block.operations) + self.newexitswitch = spec.rename_nonvirtual(block.exitswitch, + 'exitswitch') self.newexits = self.follow_exits(block, spec) def follow_exits(self, block, spec): newlinks = [] for link in block.exits: - targetblock = link.target - for v1, v2 in zip(link.args, link.target.inputargs): - if v1 in spec.curvars: - targetblock = self.get_specialized_block(targetblock, v2) - newlink = Link(spec.expand_vars(link.args), targetblock) + targetnodes = [spec.getnode(v) for v in link.args] + specblock = self.get_specialized_block(link.target, targetnodes) + newlink = Link(spec.expand_vars(link.args), specblock) + newlink.exitcase = link.exitcase + newlink.llexitcase = link.llexitcase newlinks.append(newlink) return newlinks - def get_specialized_block(self, block, v): - specblock = self.cache.lookup_spec_block(block, (self.MALLOCTYPE, v)) + def get_specialized_block(self, orgblock, nodelist): + specblock = self.cache.lookup_spec_block(orgblock, nodelist) if specblock is None: - if block.operations == (): + if orgblock.operations == (): raise CannotVirtualize("return or except block") - spec = BlockSpecializer(self, v) - spec.make_expanded_vars() - spec.initialize_renamings(block.inputargs) - specblock = Block(spec.expand_vars(block.inputargs)) - self.pending_specializations.append((spec, block, specblock)) - self.cache.remember_spec_block(block, (self.MALLOCTYPE, v), - specblock) + spec = BlockSpecializer(self) + spec.initialize_renamings(orgblock.inputargs, nodelist) + specblock = Block(spec.expand_vars(orgblock.inputargs)) + self.pending_specializations.append((spec, orgblock, specblock)) + self.cache.remember_spec_block(orgblock, nodelist, specblock) return specblock def get_specialized_graph(self, graph, v): block = graph.startblock specblock = self.get_specialized_block(block, v) + if specblock is block: + return graph specgraph = self.cache.lookup_graph_starting_at(specblock) if specgraph is None: specgraph = FunctionGraph(graph.name + '_spec', specblock) @@ -176,61 +275,57 @@ while self.pending_specializations: spec, block, specblock = self.pending_specializations.pop() specblock.operations = spec.specialize_operations(block.operations) + specblock.exitswitch = spec.rename_nonvirtual(block.exitswitch, + 'exitswitch') specblock.closeblock(*self.follow_exits(block, spec)) def commit(self): self.startblock.inputargs = self.newinputargs self.startblock.operations = self.newoperations + self.startblock.exitswitch = self.newexitswitch self.startblock.recloseblock(*self.newexits) self.cache.push_changes() class BlockSpecializer(object): - def __init__(self, mallocspec, v): + def __init__(self, mallocspec, v_expand_malloc=None): self.mallocspec = mallocspec - self.curvars = set([v]) + self.v_expand_malloc = v_expand_malloc - def make_expanded_vars(self): - self.expanded_v = [] - for name, FIELDTYPE in self.mallocspec.names_and_types: - v = Variable(name) - v.concretetype = FIELDTYPE - self.expanded_v.append(v) - - def make_expanded_zero_constants(self): - self.expanded_v = [] - for name, FIELDTYPE in self.mallocspec.names_and_types: - c = Constant(FIELDTYPE._defl()) - c.concretetype = FIELDTYPE - self.expanded_v.append(c) + def initialize_renamings(self, inputargs, inputnodes): + assert len(inputargs) == len(inputnodes) + self.nodes = {} + self.renamings = {} # {RuntimeSpecNode(): Variable()} + memo = {} + for v, node in zip(inputargs, inputnodes): + newnode = node.copy(self.fresh_rtnode, v, v.concretetype, memo) + self.setnode(v, newnode) + + def setnode(self, v, node): + assert v not in self.nodes + self.nodes[v] = node + + def getnode(self, v): + if isinstance(v, Variable): + return self.nodes[v] + else: + rtnode = RuntimeSpecNode() + self.renamings[rtnode] = v + return rtnode def rename_nonvirtual(self, v, where=None): - if isinstance(v, Constant): + if not isinstance(v, Variable): return v - if v in self.curvars: + node = self.nodes[v] + if not isinstance(node, RuntimeSpecNode): raise CannotVirtualize(where) - [v2] = self.renamings[v] - return v2 + return self.renamings[node] def expand_vars(self, vars): - result_v = [] - for v in vars: - if isinstance(v, Variable): - result_v += self.renamings[v] - else: - result_v.append(v) - return result_v - - def initialize_renamings(self, inputargs): - self.renamings = {} - for v in inputargs: - if v in self.curvars: - self.renamings[v] = self.expanded_v - else: - v2 = Variable(v) - v2.concretetype = v.concretetype - self.renamings[v] = [v2] + nodelist = [self.getnode(v) for v in vars] + rtnodes = find_rt_nodes(nodelist) + return [self.renamings[rtnode] for rtnode in rtnodes] def specialize_operations(self, operations): newoperations = [] @@ -240,75 +335,75 @@ newoperations += meth(op) return newoperations + def fresh_rtnode(self, name, TYPE): + newvar = Variable(name) + newvar.concretetype = TYPE + newrtnode = RuntimeSpecNode() + self.renamings[newrtnode] = newvar + return newrtnode + + def make_rt_result(self, v_result): + rtnode = self.fresh_rtnode(v_result, v_result.concretetype) + self.setnode(v_result, rtnode) + return self.renamings[rtnode] + def handle_default(self, op): newargs = [self.rename_nonvirtual(v, op) for v in op.args] - newresult = Variable(op.result) - newresult.concretetype = op.result.concretetype - self.renamings[op.result] = [newresult] + newresult = self.make_rt_result(op.result) return [SpaceOperation(op.opname, newargs, newresult)] def handle_op_getfield(self, op): - if op.args[0] in self.curvars: + node = self.getnode(op.args[0]) + if isinstance(node, VirtualSpecNode): fieldname = op.args[1].value - index = self.mallocspec.name2index[fieldname] - v_field = self.expanded_v[index] - self.renamings[op.result] = [v_field] + index = node.typedesc.name2index[fieldname] + self.setnode(op.result, node.fields[index]) return [] else: return self.handle_default(op) def handle_op_setfield(self, op): - if op.args[0] in self.curvars: + node = self.getnode(op.args[0]) + if isinstance(node, VirtualSpecNode): fieldname = op.args[1].value - index = self.mallocspec.name2index[fieldname] - self.expanded_v[index] = self.rename_nonvirtual(op.args[2], op) + index = node.typedesc.name2index[fieldname] + node.fields[index] = self.getnode(op.args[2]) return [] else: return self.handle_default(op) def handle_op_malloc(self, op): - if op.result in self.curvars: - self.make_expanded_zero_constants() - self.renamings[op.result] = self.expanded_v + if op.result is self.v_expand_malloc: + typedesc = self.mallocspec.malloctypedesc + virtualnode = VirtualSpecNode(typedesc, []) + self.setnode(op.result, virtualnode) + for name, FIELDTYPE in typedesc.names_and_types: + fieldnode = RuntimeSpecNode() + virtualnode.fields.append(fieldnode) + c = Constant(FIELDTYPE._defl()) + c.concretetype = FIELDTYPE + self.renamings[fieldnode] = c return [] else: return self.handle_default(op) def handle_op_direct_call(self, op): fobj = op.args[0].value._obj - if hasattr(fobj, 'graph'): - graph = fobj.graph - if self.mallocspec.immutable_struct: - return self.handle_call_with_immutable(op, graph) - else: - return self.handle_call_with_mutable(op, graph) - else: + if not hasattr(fobj, 'graph'): return self.handle_default(op) - - def handle_call_with_immutable(self, op, graph): + graph = fobj.graph nb_args = len(op.args) - 1 assert nb_args == len(graph.getargs()) - newargs = [] - for i in range(nb_args): - v1 = op.args[1+i] - if v1 not in self.curvars: - newargs.append(v1) - else: - inputarg_index_in_specgraph = len(newargs) - v2 = graph.getargs()[inputarg_index_in_specgraph] - assert v1.concretetype == v2.concretetype - specgraph = self.mallocspec.get_specialized_graph(graph, v2) - newargs.extend(self.expanded_v) - graph = specgraph - assert len(newargs) == len(graph.getargs()) - fspecptr = getfunctionptr(graph) - newargs.insert(0, Constant(fspecptr, - concretetype=lltype.typeOf(fspecptr))) - newresult = Variable(op.result) - newresult.concretetype = op.result.concretetype - self.renamings[op.result] = [newresult] + newnodes = [self.getnode(v) for v in op.args[1:]] + if contains_mutable(newnodes): + return self.handle_default(op) + newgraph = self.mallocspec.get_specialized_graph(graph, newnodes) + if newgraph is graph: + return self.handle_default(op) + fspecptr = getfunctionptr(newgraph) + newargs = [Constant(fspecptr, + concretetype=lltype.typeOf(fspecptr))] + newargs += self.expand_vars(op.args[1:]) + newresult = self.make_rt_result(op.result) newop = SpaceOperation('direct_call', newargs, newresult) return [newop] - - def handle_call_with_mutable(self, op, graph): - return self.handle_default(op) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Wed Oct 8 11:36:08 2008 @@ -72,6 +72,21 @@ insns = summary(graph) assert insns['int_mul'] == 1 + def test_aliasing1(self): + A = lltype.GcStruct('A', ('x', lltype.Signed)) + def fn1(x): + a1 = lltype.malloc(A) + a1.x = 123 + if x > 0: + a2 = a1 + else: + a2 = lltype.malloc(A) + a2.x = 456 + a1.x += 1 + return a2.x + self.check(fn1, [int], [3], 124) + self.check(fn1, [int], [-3], 456) + def test_direct_call(self): def g(t): a, b = t From jlg at codespeak.net Wed Oct 8 11:46:36 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Wed, 8 Oct 2008 11:46:36 +0200 (CEST) Subject: [pypy-svn] r58796 - in pypy/branch/2.5-merge/pypy/module/operator: . test Message-ID: <20081008094636.20D7C169FDA@codespeak.net> Author: jlg Date: Wed Oct 8 11:46:35 2008 New Revision: 58796 Modified: pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Log: irepeat() checks for type of arguments Modified: pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py Wed Oct 8 11:46:35 2008 @@ -228,7 +228,13 @@ def irepeat(space, w_obj1, w_obj2): 'irepeat(a, b) -- Same as a *= b, for a and b sequences.' if space.findattr(w_obj1, space.wrap('__getitem__')) is None: - raise OperationError(space.w_TypeError, space.w_None) + # first arg has to be a sequence + raise OperationError(space.w_TypeError, "non-sequence object can't be repeated") + + if not (space.is_true(space.isinstance(w_obj2, space.w_int)) or \ + space.is_true(space.isinstance(w_obj2, space.w_long))): + # second arg has to be int/long + raise OperationError(space.w_TypeError, 'an integer is required') return space.inplace_mul(w_obj1, w_obj2) Modified: pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/test/test_operator.py Wed Oct 8 11:46:35 2008 @@ -152,3 +152,22 @@ assert operator.imul(list, 2) is list assert list == [1, 2, 1, 2] + def test_irepeat(self): + import operator + import py + + class X(object): + def __index__(self): + return 5 + + a = range(3) + raises(TypeError, operator.irepeat) + raises(TypeError, operator.irepeat, a, None) + raises(TypeError, operator.irepeat, a, []) + raises(TypeError, operator.irepeat, a, X()) + raises(TypeError, operator.irepeat, 6, 7) + assert operator.irepeat(a, 2L) is a + assert a == [0, 1, 2, 0, 1, 2] + assert operator.irepeat(a, 1) is a + assert a == [0, 1, 2, 0, 1, 2] + From fijal at codespeak.net Wed Oct 8 11:52:04 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 8 Oct 2008 11:52:04 +0200 (CEST) Subject: [pypy-svn] r58797 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081008095204.F419E169FD2@codespeak.net> Author: fijal Date: Wed Oct 8 11:52:04 2008 New Revision: 58797 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/generation.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/hybrid.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py Log: Move stuff around to avoid having obscure details in base. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py Wed Oct 8 11:52:04 2008 @@ -186,18 +186,10 @@ def debug_check_object(self, obj): pass - -TYPEID_MASK = 0xffff first_gcflag = 1 << 16 -GCFLAG_FORWARDED = first_gcflag -# GCFLAG_EXTERNAL is set on objects not living in the semispace: -# either immortal objects or (for HybridGC) externally raw_malloc'ed -GCFLAG_EXTERNAL = first_gcflag << 1 -GCFLAG_FINALIZATION_ORDERING = first_gcflag << 2 class MovingGCBase(GCBase): moving_gc = True - first_unused_gcflag = first_gcflag << 3 def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE): GCBase.__init__(self) @@ -223,26 +215,10 @@ addr -= self.gcheaderbuilder.size_gc_header return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) - def get_type_id(self, addr): - tid = self.header(addr).tid - ll_assert(tid & (GCFLAG_FORWARDED|GCFLAG_EXTERNAL) != GCFLAG_FORWARDED, - "get_type_id on forwarded obj") - # Non-prebuilt forwarded objects are overwritten with a FORWARDSTUB. - # Although calling get_type_id() on a forwarded object works by itself, - # we catch it as an error because it's likely that what is then - # done with the typeid is bogus. - return tid & TYPEID_MASK - def init_gc_object(self, addr, typeid, flags=0): hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) hdr.tid = typeid | flags - def init_gc_object_immortal(self, addr, typeid, flags=0): - hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) - hdr.tid = typeid | flags | GCFLAG_EXTERNAL | GCFLAG_FORWARDED - # immortal objects always have GCFLAG_FORWARDED set; - # see get_forwarding_address(). - def get_size(self, obj): typeid = self.get_type_id(obj) size = self.fixed_size(typeid) @@ -268,7 +244,6 @@ if free_after_collection < self.space_size // 5: self.red_zone += 1 - def choose_gc_from_config(config): """Return a (GCClass, GC_PARAMS) from the given config object. """ Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/generation.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/generation.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/generation.py Wed Oct 8 11:52:04 2008 @@ -1,6 +1,6 @@ import sys from pypy.rpython.memory.gc.semispace import SemiSpaceGC -from pypy.rpython.memory.gc.base import GCFLAG_EXTERNAL, GCFLAG_FORWARDED +from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED from pypy.rpython.memory.gc.semispace import DEBUG_PRINT from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage from pypy.rpython.lltypesystem import lltype, llmemory, llarena Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/hybrid.py Wed Oct 8 11:52:04 2008 @@ -2,7 +2,7 @@ from pypy.rpython.memory.gc.semispace import SemiSpaceGC from pypy.rpython.memory.gc.semispace import DEBUG_PRINT from pypy.rpython.memory.gc.generation import GenerationGC -from pypy.rpython.memory.gc.base import GCFLAG_EXTERNAL, GCFLAG_FORWARDED +from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED from pypy.rpython.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS from pypy.rpython.memory.gc.generation import GCFLAG_NO_HEAP_PTRS from pypy.rpython.lltypesystem import lltype, llmemory, llarena Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 8 11:52:04 2008 @@ -1,7 +1,6 @@ from pypy.rpython.lltypesystem import lltype, llmemory, llarena -from pypy.rpython.memory.gc.base import MovingGCBase, \ - TYPEID_MASK, GCFLAG_FINALIZATION_ORDERING, GCFLAG_EXTERNAL +from pypy.rpython.memory.gc.base import MovingGCBase from pypy.rlib.debug import ll_assert from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE from pypy.rpython.memory.support import get_address_stack, get_address_deque @@ -10,8 +9,11 @@ from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.objectmodel import we_are_translated +from pypy.rpython.memory.gc.base import first_gcflag -GCFLAG_MARKBIT = MovingGCBase.first_unused_gcflag +TYPEID_MASK = 0xffff +GCFLAG_MARKBIT = first_gcflag << 3 +GCFLAG_EXTERNAL = GCFLAG_MARKBIT << 4 memoryError = MemoryError() @@ -327,7 +329,7 @@ if resizing: end = fromaddr hdr.forward_ptr = NULL - hdr.tid &= ~(GCFLAG_MARKBIT|GCFLAG_FINALIZATION_ORDERING) + hdr.tid &= ~GCFLAG_MARKBIT if fromaddr != forward_ptr: #llop.debug_print(lltype.Void, "Copying from to", # fromaddr, forward_ptr, totalsize) Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py Wed Oct 8 11:52:04 2008 @@ -9,20 +9,25 @@ from pypy.rlib.debug import ll_assert from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.rarithmetic import ovfcheck -from pypy.rpython.memory.gc.base import MovingGCBase, GCFLAG_EXTERNAL -from pypy.rpython.memory.gc.base import GCFLAG_FORWARDED -from pypy.rpython.memory.gc.base import GCFLAG_FINALIZATION_ORDERING +from pypy.rpython.memory.gc.base import MovingGCBase, first_gcflag import sys, os DEBUG_PRINT = False memoryError = MemoryError() +TYPEID_MASK = 0xffff +GCFLAG_FORWARDED = first_gcflag +# GCFLAG_EXTERNAL is set on objects not living in the semispace: +# either immortal objects or (for HybridGC) externally raw_malloc'ed +GCFLAG_EXTERNAL = first_gcflag << 1 +GCFLAG_FINALIZATION_ORDERING = first_gcflag << 2 class SemiSpaceGC(MovingGCBase): _alloc_flavor_ = "raw" inline_simple_malloc = True inline_simple_malloc_varsize = True malloc_zero_filled = True + first_unused_gcflag = first_gcflag << 3 total_collection_time = 0.0 total_collection_count = 0 @@ -54,6 +59,22 @@ self.free = self.tospace MovingGCBase.setup(self) + def init_gc_object_immortal(self, addr, typeid, flags=0): + hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) + hdr.tid = typeid | flags | GCFLAG_EXTERNAL | GCFLAG_FORWARDED + # immortal objects always have GCFLAG_FORWARDED set; + # see get_forwarding_address(). + + def get_type_id(self, addr): + tid = self.header(addr).tid + ll_assert(tid & (GCFLAG_FORWARDED|GCFLAG_EXTERNAL) != GCFLAG_FORWARDED, + "get_type_id on forwarded obj") + # Non-prebuilt forwarded objects are overwritten with a FORWARDSTUB. + # Although calling get_type_id() on a forwarded object works by itself, + # we catch it as an error because it's likely that what is then + # done with the typeid is bogus. + return tid & TYPEID_MASK + # This class only defines the malloc_{fixed,var}size_clear() methods # because the spaces are filled with zeroes in advance. From witulski at codespeak.net Wed Oct 8 11:54:46 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Wed, 8 Oct 2008 11:54:46 +0200 (CEST) Subject: [pypy-svn] r58798 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081008095446.A37B3169FD2@codespeak.net> Author: witulski Date: Wed Oct 8 11:54:46 2008 New Revision: 58798 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py Log: merged Register64 and Register8 to IntVar(preperation for spilling) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Wed Oct 8 11:54:46 2008 @@ -1,6 +1,6 @@ -from pypy.jit.codegen.x86_64.objmodel import Register8, Register64, Immediate8, Immediate32, Immediate64 +from pypy.jit.codegen.x86_64.objmodel import IntVar, Immediate8, Immediate32, Immediate64 -#Mapping from 64Bit-Register to coding (Rex.W or Rex.B , ModRM) +# Mapping from 64Bit-Register to coding (Rex.W or Rex.B , ModRM) REGISTER_MAP = { "rax": (0, 0), "rcx": (0, 1), @@ -44,10 +44,11 @@ rexX = X rexB = B # TODO: other cases e.g memory as operand - if isinstance(arg1,Register64): - rexB, modrm1 = self.get_register_bits(arg1.reg) - elif isinstance(arg1,Register8): - modrm1 = self.get_register_bits_8Bit(arg1.reg) + if isinstance(arg1,IntVar): + if arg1.location_type == "Register64": + rexB, modrm1 = self.get_register_bits(arg1.pos_str) + elif arg1.location_type == "Register8": + modrm1 = self.get_register_bits_8Bit(arg1.pos_str) # exchange the two arguments (modrm2/modrm1) if isinstance(arg2,Immediate32): @@ -64,15 +65,16 @@ self.write(opcode) self.write_modRM_byte(3, modrm2, modrm1) self.write(chr(arg2.value)) - elif isinstance(arg2,Register64): - rexR, modrm2 = self.get_register_bits(arg2.reg) - # FIXME: exchange the two arguments (rexB/rexR) - self.write_rex_byte(rexW, rexR, rexX, rexB) - self.write(opcode) - # used in imul (extra long opcode) - if not extra == None: - self.write(extra) - self.write_modRM_byte(mod, modrm2, modrm1) + elif isinstance(arg2, IntVar): + if arg2.location_type == "Register64": + rexR, modrm2 = self.get_register_bits(arg2.pos_str) + # FIXME: exchange the two arguments (rexB/rexR) + self.write_rex_byte(rexW, rexR, rexX, rexB) + self.write(opcode) + # used in imul (extra long opcode) + if not extra == None: + self.write(extra) + self.write_modRM_byte(mod, modrm2, modrm1) return quadreg_instr @@ -93,10 +95,11 @@ rexB = B # TODO: other cases e.g memory as operand - if isinstance(arg1,Register64): - rexB, modrm1 = self.get_register_bits(arg1.reg) - if isinstance(arg1,Register8): - modrm1 = self.get_register_bits_8Bit(arg1.reg) + if isinstance(arg1, IntVar): + if arg1.location_type == "Register64": + rexB, modrm1 = self.get_register_bits(arg1.pos_str) + elif arg1.location_type == "Register8": + modrm1 = self.get_register_bits_8Bit(arg1.pos_str) # rexW(1) = 64bitMode self.write_rex_byte(rexW, rexR, rexX, rexB) @@ -107,7 +110,8 @@ self.write_modRM_byte(mod, modrm2, modrm1) return quadreg_instr -# TODO: comment +# When using an alternate encoding the opcode +# depends on the used register X0 to XF. def make_two_operand_instr_with_alternate_encoding(W = None, R = None, X = None, B = None, opcode =None, md1 = None, md2 = None): def quadreg_instr(self, arg1, arg2): # move the parameter @@ -120,10 +124,11 @@ rexB = B # TODO: other cases e.g memory as operand # FIXME: rexB? - if isinstance(arg1,Register64): - rexB, modrm1 = self.get_register_bits(arg1.reg) + if isinstance(arg1, IntVar): + if arg1.location_type == "Register64": + rexB, modrm1 = self.get_register_bits(arg1.pos_str) - if isinstance(arg2,Immediate64): + if isinstance(arg2, Immediate64): new_opcode = hex(int(opcode,16)+modrm1) assert len(new_opcode[2:len(new_opcode)]) == 2 self.write_rex_byte(rexW, rexR, rexX, rexB) @@ -143,12 +148,13 @@ rexB = B # TODO: other cases e.g memory as operand # FIXME: rexB? - if isinstance(arg1,Register64): - rexB, modrm1 = self.get_register_bits(arg1.reg) - new_opcode = hex(int(opcode,16)+modrm1) - assert len(new_opcode[2:len(new_opcode)]) == 2 - self.write_rex_byte(rexW, rexR, rexX, rexB) - self.write(chr(int(new_opcode[2:len(new_opcode)],16))) + if isinstance(arg1, IntVar): + if arg1.location_type == "Register64": + rexB, modrm1 = self.get_register_bits(arg1.pos_str) + new_opcode = hex(int(opcode,16)+modrm1) + assert len(new_opcode[2:len(new_opcode)]) == 2 + self.write_rex_byte(rexW, rexR, rexX, rexB) + self.write(chr(int(new_opcode[2:len(new_opcode)],16))) return quadreg_instr class X86_64CodeBuilder(object): @@ -266,7 +272,7 @@ # 4 length of the immediate def JMP(self,want_jump_to): #method = getattr(self, "_JMP"+op1.to_string()) - #method(op1) + #method(want_jump_to) self.write("\xE9") self.writeImm32(want_jump_to-self.tell()-4) @@ -281,7 +287,7 @@ method = getattr(self, "_OR"+op1.to_string()+op2.to_string()) method(op1, op2) - #fixme:none + #FIXME: "POP/PUSH NONE" BUG def POP(self, op1): method = getattr(self, "_POP"+op1.to_string()) method(op1) @@ -406,7 +412,9 @@ byte = mod << 6 | (reg << 3) | rm self.write(chr(byte)) - # TODO: write comment + # calc. the "Two's complement" + # and return as pos. hex value. + # This method is used to calc jump displ. def cast_neg_hex32(self,a_int): x = hex(int("FFFFFFFF",16)+1 +a_int) y = x[2:len(x)] Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py Wed Oct 8 11:54:46 2008 @@ -1,23 +1,22 @@ from pypy.jit.codegen import model from pypy.rpython.lltypesystem import lltype, rffi, llmemory -# Wrapper Classes -# The opcaodes differ from the type of -# the operand. So every wrapper is necessary -# The to string method is used to choose the right +# Wrapper Classes: +# The opcodes(assemble.py) differ from the type of +# the operand(eg. Register, Immediate...). +# The to_string method is used to choose the right # method inside the assembler -class Register8(model.GenVar): - def __init__(self, reg): - self.reg = reg - - def to_string(self): - return "_8REG" -class Register64(model.GenVar): - def __init__(self, reg): - self.reg = reg - +class IntVar(model.GenVar): + def __init__(self, pos_str, location_type): + self.pos_str = pos_str + self.location_type = location_type + assert location_type == "Register64" or location_type == "Register8" + def to_string(self): - return "_QWREG" + if self.location_type=="Register8": + return "_8REG" + elif self.location_type=="Register64": + return "_QWREG" class Immediate8(model.GenConst): def __init__(self, value): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Wed Oct 8 11:54:46 2008 @@ -1,6 +1,6 @@ from pypy.jit.codegen import model from pypy.rlib.objectmodel import specialize -from pypy.jit.codegen.x86_64.objmodel import Register8, Register64, Immediate8, Immediate32, Immediate64 +from pypy.jit.codegen.x86_64.objmodel import IntVar, Immediate8, Immediate32, Immediate64 from pypy.jit.codegen.x86_64.codebuf import InMemoryCodeBuilder #TODO: understand llTypesystem from pypy.rpython.lltypesystem import llmemory, lltype @@ -63,7 +63,7 @@ self.moves = [] def create_fresh_location(self): - return self.builder.allocate_register().reg + return self.builder.allocate_register().pos_str def emit_move(self, source, target): self.moves.append((source, target)) @@ -94,7 +94,7 @@ } self.known_gv = [] for reg in used_registers: - self.allocate_register(reg.reg) + self.allocate_register(reg.pos_str) def _open(self): pass @@ -124,7 +124,7 @@ # TODO: support reg8 def op_cast_bool_to_int(self, gv_x): - assert isinstance(gv_x, Register64) + assert isinstance(gv_x, IntVar) and gv_x.location_type == "Register64" return gv_x # 0 xor 1 == 1 @@ -183,38 +183,38 @@ # choose rax,rcx or rdx # TODO: use also rcx rdx gv_z = self.allocate_register("rax") - self.mc.SETG(Register8("al")) - return Register64("rax") + self.mc.SETG(IntVar("al","Register8")) + return IntVar("rax", "Register64") def op_int_lt(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETL(Register8("al")) - return Register64("rax") + self.mc.SETL(IntVar("al","Register8")) + return IntVar("rax", "Register64") def op_int_le(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETLE(Register8("al")) - return Register64("rax") + self.mc.SETLE(IntVar("al","Register8")) + return IntVar("rax", "Register64") def op_int_eq(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETE(Register8("al")) - return Register64("rax") + self.mc.SETE(IntVar("al","Register8")) + return IntVar("rax", "Register64") def op_int_ne(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETNE(Register8("al")) - return Register64("rax") + self.mc.SETNE(IntVar("al","Register8")) + return IntVar("rax", "Register64") def op_int_ge(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETGE(Register8("al")) - return Register64("rax") + self.mc.SETGE(IntVar("al","Register8")) + return IntVar("rax", "Register64") # the moves to pass arg. when making a jump to a block def _compute_moves(self, outputargs_gv, targetargs_gv): @@ -222,13 +222,13 @@ tar2loc = {} src2loc = {} for i in range(len(outputargs_gv)): - target_gv = targetargs_gv[i].reg - source_gv = outputargs_gv[i].reg + target_gv = targetargs_gv[i].pos_str + source_gv = outputargs_gv[i].pos_str tar2src[target_gv] = source_gv tar2loc[target_gv] = target_gv src2loc[source_gv] = source_gv movegen = MoveEmitter(self) - emit_moves(movegen, [target_gv.reg for target_gv in targetargs_gv], + emit_moves(movegen, [target_gv.pos_str for target_gv in targetargs_gv], tar2src, tar2loc, src2loc) return movegen.moves @@ -237,7 +237,9 @@ #FIXME: imm8 insted of imm32? def _new_jump(name, value): from pypy.tool.sourcetools import func_with_new_name - def jump(self, gv_condition, args_for_jump_gv): + def jump(self, gv_condition, args_for_jump_gv): + # the targetbuilder must know the registers(live vars) + # of the calling block targetbuilder = Builder(args_for_jump_gv) self.mc.CMP(gv_condition, Immediate32(value)) self.mc.JNE(targetbuilder.mc.tell()) @@ -251,7 +253,7 @@ #self.mc.write("\xB8\x0F\x00\x00\x00") self._open() if not gv_returnvar == None:#check void return - self.mc.MOV(Register64("rax"), gv_returnvar) + self.mc.MOV(IntVar("rax", "Register64"), gv_returnvar) self.mc.RET() self._close() @@ -266,7 +268,7 @@ #self.mc.JMP(gv_x) moves = self._compute_moves(outputargs_gv, target.arg_positions) for source_gv, target_gv in moves: - self.mc.MOV(Register64(source_gv), Register64(target_gv)) + self.mc.MOV(IntVar(source_gv, "Register64"), IntVar(target_gv, "Register64")) self.mc.JMP(target.startaddr) self._close() @@ -276,25 +278,25 @@ if not self.freeregisters: raise NotImplementedError("spilling not implemented") - new_gv = Register64(self.freeregisters.popitem()[0]) + new_gv = IntVar((self.freeregisters.popitem()[0]), "Register64") self.known_gv.append(new_gv) return new_gv else: if register not in self.freeregisters: # the register must be in the list! for i in range(len(self.known_gv)): - if register == self.known_gv[i].reg: + if register == self.known_gv[i].pos_str: # move the values from the requiered register # to an other one and return the # requested one. gv = self.allocate_register() self.mc.MOV(gv,self.known_gv[i]) - new_gv = Register64(register) + new_gv = IntVar(register, "Register64") self.known_gv.append(new_gv) return new_gv raise NotImplementedError("register moves") del self.freeregisters[register] - new_gv = Register64(register) + new_gv = IntVar(register, "Register64") self.known_gv.append(new_gv) return new_gv @@ -325,6 +327,8 @@ is not lltype.Void], map_arg(FUNCTYPE.RESULT)) # wrappes a integer value + # many 64-bit operations only + # support 32-bit immediates def genconst(self, llvalue): T = lltype.typeOf(llvalue) # TODO: other cases(?),imm64 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py Wed Oct 8 11:54:46 2008 @@ -1,5 +1,5 @@ from pypy.jit.codegen.x86_64 import assembler -from pypy.jit.codegen.x86_64.objmodel import Register64, Immediate32 +from pypy.jit.codegen.x86_64.objmodel import IntVar, Immediate32 class AsmTest(assembler.X86_64CodeBuilder): def __init__(self): @@ -13,12 +13,12 @@ def test_add(): mc = AsmTest() - mc.ADD(Register64("rax"), Register64("r11")) + mc.ADD(IntVar("rax", "Register64"), IntVar("r11", "Register64")) assert mc.get_as_string() == "\x4C\x01\xD8" - mc.ADD(Register64("rbx"), Register64("rbx")) + mc.ADD(IntVar("rbx", "Register64"), IntVar("rbx", "Register64")) assert mc.get_as_string() == "\x4C\x01\xD8\x48\x01\xDB" def test_mov(): mc = AsmTest() - mc.MOV(Register64("r15"),Register64("rsp")) + mc.MOV(IntVar("r15", "Register64"), IntVar("rsp", "Register64")) assert mc.get_as_string() == "\x49\x89\xE7" \ No newline at end of file Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py Wed Oct 8 11:54:46 2008 @@ -4,7 +4,7 @@ from pypy.jit.codegen.x86_64.rgenop import RX86_64GenOp from pypy.rpython.lltypesystem import lltype from ctypes import cast, c_void_p, CFUNCTYPE, c_long, c_double -from pypy.jit.codegen.x86_64.objmodel import Register64, Immediate32 +#from pypy.jit.codegen.x86_64.objmodel import Immediate32 from pypy.jit.codegen.test.rgenop_tests import AbstractTestBase from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTestsDirect From fijal at codespeak.net Wed Oct 8 11:58:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 8 Oct 2008 11:58:33 +0200 (CEST) Subject: [pypy-svn] r58799 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081008095833.383D4169FED@codespeak.net> Author: fijal Date: Wed Oct 8 11:58:32 2008 New Revision: 58799 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: Have a init_gc_object_immortal in markcompact gc Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 8 11:58:32 2008 @@ -79,6 +79,13 @@ hdr.tid = typeid | flags hdr.forward_ptr = NULL + def init_gc_object_immortal(self, addr, typeid, flags=0): + hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) + hdr.tid = typeid | flags | GCFLAG_EXTERNAL + hdr.forward_ptr = NULL + # immortal objects always have GCFLAG_FORWARDED set; + # see get_forwarding_address(). + def malloc_fixedsize_clear(self, typeid, size, can_collect, has_finalizer=False, contains_weakptr=False): assert can_collect From hpk at codespeak.net Wed Oct 8 13:14:40 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 8 Oct 2008 13:14:40 +0200 (CEST) Subject: [pypy-svn] r58800 - pypy/branch/2.5-merge/lib-python Message-ID: <20081008111440.6EF2D169EEA@codespeak.net> Author: hpk Date: Wed Oct 8 13:14:38 2008 New Revision: 58800 Modified: pypy/branch/2.5-merge/lib-python/conftest.py Log: (pedronis,hpk) correctly fix the setup/teardown problem Modified: pypy/branch/2.5-merge/lib-python/conftest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/conftest.py (original) +++ pypy/branch/2.5-merge/lib-python/conftest.py Wed Oct 8 13:14:38 2008 @@ -67,11 +67,6 @@ self.core = core assert self.getfspath().check(), "%r not found!" % (basename,) - def setup(self): - pass - def teardown(self): - pass - def usemodules(self): return self._usemodules #+ pypy_option.usemodules usemodules = property(usemodules) @@ -581,7 +576,7 @@ Directory = RegrDirectory -class RunFileExternal(py.test.collect.Module): +class RunFileExternal(py.test.collect.File): def __init__(self, name, parent, regrtest): super(RunFileExternal, self).__init__(name, parent) self.regrtest = regrtest From arigo at codespeak.net Wed Oct 8 13:35:26 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 13:35:26 +0200 (CEST) Subject: [pypy-svn] r58801 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081008113526.F3144169EAE@codespeak.net> Author: arigo Date: Wed Oct 8 13:35:24 2008 New Revision: 58801 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/hybrid.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/marksweep.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py Log: (fijal, arigo) Shuffle stuff around. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py Wed Oct 8 13:35:24 2008 @@ -14,6 +14,13 @@ prebuilt_gc_objects_are_static_roots = True can_realloc = False + def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE): + self.gcheaderbuilder = GCHeaderBuilder(self.HDR) + self.AddressStack = get_address_stack(chunk_size) + self.AddressDeque = get_address_deque(chunk_size) + self.AddressDict = AddressDict + self.finalizer_lock_count = 0 + def can_malloc_nonmovable(self): return not self.moving_gc @@ -51,7 +58,7 @@ pass def setup(self): - pass + self.run_finalizers = self.AddressDeque() def statistics(self, index): return -1 @@ -186,27 +193,40 @@ def debug_check_object(self, obj): pass -first_gcflag = 1 << 16 + def get_size(self, obj): + typeid = self.get_type_id(obj) + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + lenaddr = obj + self.varsize_offset_to_length(typeid) + length = lenaddr.signed[0] + size += length * self.varsize_item_sizes(typeid) + size = llarena.round_up_for_allocation(size) + # XXX maybe we should parametrize round_up_for_allocation() + # per GC; if we do, we also need to fix the call in + # gctypelayout.encode_type_shape() + return size + + def execute_finalizers(self): + self.finalizer_lock_count += 1 + try: + while self.run_finalizers.non_empty(): + if self.finalizer_lock_count > 1: + # the outer invocation of execute_finalizers() will do it + break + obj = self.run_finalizers.popleft() + finalizer = self.getfinalizer(self.get_type_id(obj)) + finalizer(obj) + finally: + self.finalizer_lock_count -= 1 class MovingGCBase(GCBase): moving_gc = True def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE): - GCBase.__init__(self) - self.gcheaderbuilder = GCHeaderBuilder(self.HDR) - self.AddressStack = get_address_stack(chunk_size) - self.AddressDeque = get_address_deque(chunk_size) - self.AddressDict = AddressDict - self.finalizer_lock_count = 0 + GCBase.__init__(self, chunk_size) + self.objects_with_id = self.AddressDict() self.id_free_list = self.AddressStack() self.next_free_id = 1 - self.red_zone = 0 - - def setup(self): - self.objects_with_finalizers = self.AddressDeque() - self.run_finalizers = self.AddressDeque() - self.objects_with_weakrefs = self.AddressStack() - self.objects_with_id = self.AddressDict() def can_move(self, addr): return True @@ -219,30 +239,59 @@ hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) hdr.tid = typeid | flags - def get_size(self, obj): - typeid = self.get_type_id(obj) - size = self.fixed_size(typeid) - if self.is_varsize(typeid): - lenaddr = obj + self.varsize_offset_to_length(typeid) - length = lenaddr.signed[0] - size += length * self.varsize_item_sizes(typeid) - size = llarena.round_up_for_allocation(size) - return size + def id(self, ptr): + # Default implementation for id(), assuming that "external" objects + # never move. Overriden in the HybridGC. + obj = llmemory.cast_ptr_to_adr(ptr) + if self._is_external(obj): + result = obj + else: + result = self._compute_id(obj) + return llmemory.cast_adr_to_int(result) - def record_red_zone(self): - # red zone: if the space is more than 80% full, the next collection - # should double its size. If it is more than 66% full twice in a row, - # then it should double its size too. (XXX adjust) - # The goal is to avoid many repeated collection that don't free a lot - # of memory each, if the size of the live object set is just below the - # size of the space. - free_after_collection = self.top_of_space - self.free - if free_after_collection > self.space_size // 3: - self.red_zone = 0 + def _next_id(self): + # return an id not currently in use (as an address instead of an int) + if self.id_free_list.non_empty(): + result = self.id_free_list.pop() # reuse a dead id + else: + # make up a fresh id number + result = llmemory.cast_int_to_adr(self.next_free_id) + self.next_free_id += 2 # only odd numbers, to make lltype + # and llmemory happy and to avoid + # clashes with real addresses + return result + + def _compute_id(self, obj): + # look if the object is listed in objects_with_id + result = self.objects_with_id.get(obj) + if not result: + result = self._next_id() + self.objects_with_id.setitem(obj, result) + return result + + def update_objects_with_id(self): + old = self.objects_with_id + new_objects_with_id = self.AddressDict(old.length()) + old.foreach(self._update_object_id_FAST, new_objects_with_id) + old.delete() + self.objects_with_id = new_objects_with_id + + def _update_object_id(self, obj, id, new_objects_with_id): + # safe version (used by subclasses) + if self.surviving(obj): + newobj = self.get_forwarding_address(obj) + new_objects_with_id.setitem(newobj, id) else: - self.red_zone += 1 - if free_after_collection < self.space_size // 5: - self.red_zone += 1 + self.id_free_list.append(id) + + def _update_object_id_FAST(self, obj, id, new_objects_with_id): + # unsafe version, assumes that the new_objects_with_id is large enough + if self.surviving(obj): + newobj = self.get_forwarding_address(obj) + new_objects_with_id.insertclean(newobj, id) + else: + self.id_free_list.append(id) + def choose_gc_from_config(config): """Return a (GCClass, GC_PARAMS) from the given config object. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/hybrid.py Wed Oct 8 13:35:24 2008 @@ -550,19 +550,23 @@ dead_size, "bytes in", dead_count, "objs") - def _compute_id_for_external(self, obj): - # the base classes make the assumption that all external objects - # have an id equal to their address. This is wrong if the object - # is a generation 3 rawmalloced object that initially lived in - # the semispaces. - if self.is_last_generation(obj): - # in this case, we still need to check if the object had its - # id taken before. If not, we can use its address as its id. - return self.objects_with_id.get(obj, obj) + def id(self, ptr): + obj = llmemory.cast_ptr_to_adr(ptr) + if self._is_external(obj): + # a prebuilt or rawmalloced object + if self.is_last_generation(obj): + # a generation 3 object may be one that used to live in + # the semispace. So we still need to check if the object had + # its id taken before. If not, we can use its address as its + # id as it is not going to move any more. + result = self.objects_with_id.get(obj, obj) + else: + # a generation 2 external object was never non-external in + # the past, so it cannot be listed in self.objects_with_id. + result = obj else: - # a generation 2 external object was never non-external in - # the past, so it cannot be listed in self.objects_with_id. - return obj + result = self._compute_id(obj) # common case + return llmemory.cast_adr_to_int(result) # XXX a possible optimization would be to use three dicts, one # for each generation, instead of mixing gen2 and gen3 objects. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 8 13:35:24 2008 @@ -9,11 +9,11 @@ from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.objectmodel import we_are_translated -from pypy.rpython.memory.gc.base import first_gcflag TYPEID_MASK = 0xffff -GCFLAG_MARKBIT = first_gcflag << 3 -GCFLAG_EXTERNAL = GCFLAG_MARKBIT << 4 +first_gcflag = 1 << 16 +GCFLAG_MARKBIT = first_gcflag << 0 +GCFLAG_EXTERNAL = first_gcflag << 1 memoryError = MemoryError() @@ -61,10 +61,12 @@ malloc_zero_filled = True inline_simple_malloc = True inline_simple_malloc_varsize = True + first_unused_gcflag = first_gcflag << 2 def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096): self.space_size = space_size MovingGCBase.__init__(self, chunk_size) + self.red_zone = 0 def setup(self): self.space = llarena.arena_malloc(self.space_size, True) @@ -72,7 +74,8 @@ self.free = self.space self.top_of_space = self.space + self.space_size MovingGCBase.setup(self) - self.run_finalizers = self.AddressDeque() + self.objects_with_finalizers = self.AddressDeque() + self.objects_with_weakrefs = self.AddressStack() def init_gc_object(self, addr, typeid, flags=0): hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) @@ -360,62 +363,6 @@ if not self._is_external(obj): ll_assert(not self.marked(obj), "Marked") ll_assert(not self.surviving(obj), "forward_ptr set") - - def id(self, ptr): - obj = llmemory.cast_ptr_to_adr(ptr) - if self.header(obj).tid & GCFLAG_EXTERNAL: - result = self._compute_id_for_external(obj) - else: - result = self._compute_id(obj) - return llmemory.cast_adr_to_int(result) - - def _next_id(self): - # return an id not currently in use (as an address instead of an int) - if self.id_free_list.non_empty(): - result = self.id_free_list.pop() # reuse a dead id - else: - # make up a fresh id number - result = llmemory.cast_int_to_adr(self.next_free_id) - self.next_free_id += 2 # only odd numbers, to make lltype - # and llmemory happy and to avoid - # clashes with real addresses - return result - - def _compute_id(self, obj): - # look if the object is listed in objects_with_id - result = self.objects_with_id.get(obj) - if not result: - result = self._next_id() - self.objects_with_id.setitem(obj, result) - return result - - def _compute_id_for_external(self, obj): - # For prebuilt objects, we can simply return their address. - # This method is overriden by the HybridGC. - return obj - - def update_objects_with_id(self): - old = self.objects_with_id - new_objects_with_id = self.AddressDict(old.length()) - old.foreach(self._update_object_id_FAST, new_objects_with_id) - old.delete() - self.objects_with_id = new_objects_with_id - - def _update_object_id(self, obj, id, new_objects_with_id): - # safe version (used by subclasses) - if self.surviving(obj): - newobj = self.get_forwarding_address(obj) - new_objects_with_id.setitem(newobj, id) - else: - self.id_free_list.append(id) - - def _update_object_id_FAST(self, obj, id, new_objects_with_id): - # unsafe version, assumes that the new_objects_with_id is large enough - if self.surviving(obj): - newobj = self.get_forwarding_address(obj) - new_objects_with_id.insertclean(newobj, id) - else: - self.id_free_list.append(id) def mark_objects_with_finalizers(self): new_with_finalizers = self.AddressDeque() @@ -439,19 +386,6 @@ self.objects_with_finalizers.delete() self.objects_with_finalizers = new_with_finalizers - def execute_finalizers(self): - self.finalizer_lock_count += 1 - try: - while self.run_finalizers.non_empty(): - if self.finalizer_lock_count > 1: - # the outer invocation of execute_finalizers() will do it - break - obj = self.run_finalizers.popleft() - finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj) - finally: - self.finalizer_lock_count -= 1 - def invalidate_weakrefs(self): # walk over list of objects that contain weakrefs # if the object it references survives then update the weakref @@ -474,3 +408,13 @@ (obj + offset).address[0] = NULL self.objects_with_weakrefs.delete() self.objects_with_weakrefs = new_with_weakref + + def record_red_zone(self): + # XXX KILL ME + free_after_collection = self.top_of_space - self.free + if free_after_collection > self.space_size // 3: + self.red_zone = 0 + else: + self.red_zone += 1 + if free_after_collection < self.space_size // 5: + self.red_zone += 1 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/marksweep.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/marksweep.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/marksweep.py Wed Oct 8 13:35:24 2008 @@ -42,17 +42,16 @@ TRANSLATION_PARAMS = {'start_heap_size': 8*1024*1024} # XXX adjust def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, start_heap_size=4096): + GCBase.__init__(self, chunk_size) self.heap_usage = 0 # at the end of the latest collection self.bytes_malloced = 0 # since the latest collection self.bytes_malloced_threshold = start_heap_size self.total_collection_time = 0.0 - self.AddressStack = get_address_stack(chunk_size) self.malloced_objects = lltype.nullptr(self.HDR) self.malloced_objects_with_finalizer = lltype.nullptr(self.HDR) # these are usually only the small bits of memory that make a # weakref object self.objects_with_weak_pointers = lltype.nullptr(self.HDR) - self.gcheaderbuilder = GCHeaderBuilder(self.HDR) # pools, for x_swap_pool(): # 'curpool' is the current pool, lazily allocated (i.e. NULL means # the current POOL object is not yet malloc'ed). POOL objects are Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py Wed Oct 8 13:35:24 2008 @@ -9,13 +9,14 @@ from pypy.rlib.debug import ll_assert from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.rarithmetic import ovfcheck -from pypy.rpython.memory.gc.base import MovingGCBase, first_gcflag +from pypy.rpython.memory.gc.base import MovingGCBase import sys, os DEBUG_PRINT = False memoryError = MemoryError() TYPEID_MASK = 0xffff +first_gcflag = 1 << 16 GCFLAG_FORWARDED = first_gcflag # GCFLAG_EXTERNAL is set on objects not living in the semispace: # either immortal objects or (for HybridGC) externally raw_malloc'ed @@ -46,6 +47,7 @@ MovingGCBase.__init__(self, chunk_size) self.space_size = space_size self.max_space_size = max_space_size + self.red_zone = 0 def setup(self): if DEBUG_PRINT: @@ -58,6 +60,8 @@ ll_assert(bool(self.fromspace), "couldn't allocate fromspace") self.free = self.tospace MovingGCBase.setup(self) + self.objects_with_finalizers = self.AddressDeque() + self.objects_with_weakrefs = self.AddressStack() def init_gc_object_immortal(self, addr, typeid, flags=0): hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) @@ -525,74 +529,8 @@ self.run_finalizers.delete() self.run_finalizers = new_run_finalizer - def execute_finalizers(self): - self.finalizer_lock_count += 1 - try: - while self.run_finalizers.non_empty(): - if self.finalizer_lock_count > 1: - # the outer invocation of execute_finalizers() will do it - break - obj = self.run_finalizers.popleft() - finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj) - finally: - self.finalizer_lock_count -= 1 - - def id(self, ptr): - obj = llmemory.cast_ptr_to_adr(ptr) - if self.header(obj).tid & GCFLAG_EXTERNAL: - result = self._compute_id_for_external(obj) - else: - result = self._compute_id(obj) - return llmemory.cast_adr_to_int(result) - - def _next_id(self): - # return an id not currently in use (as an address instead of an int) - if self.id_free_list.non_empty(): - result = self.id_free_list.pop() # reuse a dead id - else: - # make up a fresh id number - result = llmemory.cast_int_to_adr(self.next_free_id) - self.next_free_id += 2 # only odd numbers, to make lltype - # and llmemory happy and to avoid - # clashes with real addresses - return result - - def _compute_id(self, obj): - # look if the object is listed in objects_with_id - result = self.objects_with_id.get(obj) - if not result: - result = self._next_id() - self.objects_with_id.setitem(obj, result) - return result - - def _compute_id_for_external(self, obj): - # For prebuilt objects, we can simply return their address. - # This method is overriden by the HybridGC. - return obj - - def update_objects_with_id(self): - old = self.objects_with_id - new_objects_with_id = self.AddressDict(old.length()) - old.foreach(self._update_object_id_FAST, new_objects_with_id) - old.delete() - self.objects_with_id = new_objects_with_id - - def _update_object_id(self, obj, id, new_objects_with_id): - # safe version (used by subclasses) - if self.surviving(obj): - newobj = self.get_forwarding_address(obj) - new_objects_with_id.setitem(newobj, id) - else: - self.id_free_list.append(id) - - def _update_object_id_FAST(self, obj, id, new_objects_with_id): - # unsafe version, assumes that the new_objects_with_id is large enough - if self.surviving(obj): - newobj = self.get_forwarding_address(obj) - new_objects_with_id.insertclean(newobj, id) - else: - self.id_free_list.append(id) + def _is_external(self, obj): + return (self.header(obj).tid & GCFLAG_EXTERNAL) != 0 def debug_check_object(self, obj): """Check the invariants about 'obj' that should be true From pedronis at codespeak.net Wed Oct 8 13:40:19 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 13:40:19 +0200 (CEST) Subject: [pypy-svn] r58802 - pypy/branch/2.5-merge/pypy/module/operator Message-ID: <20081008114019.E5AB2169F0E@codespeak.net> Author: pedronis Date: Wed Oct 8 13:40:19 2008 New Revision: 58802 Modified: pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py Log: translation fix Modified: pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py (original) +++ pypy/branch/2.5-merge/pypy/module/operator/interp_operator.py Wed Oct 8 13:40:19 2008 @@ -229,12 +229,14 @@ 'irepeat(a, b) -- Same as a *= b, for a and b sequences.' if space.findattr(w_obj1, space.wrap('__getitem__')) is None: # first arg has to be a sequence - raise OperationError(space.w_TypeError, "non-sequence object can't be repeated") + raise OperationError(space.w_TypeError, + space.wrap("non-sequence object can't be repeated")) if not (space.is_true(space.isinstance(w_obj2, space.w_int)) or \ space.is_true(space.isinstance(w_obj2, space.w_long))): # second arg has to be int/long - raise OperationError(space.w_TypeError, 'an integer is required') + raise OperationError(space.w_TypeError, + space.wrap('an integer is required')) return space.inplace_mul(w_obj1, w_obj2) From pedronis at codespeak.net Wed Oct 8 13:45:04 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 13:45:04 +0200 (CEST) Subject: [pypy-svn] r58803 - pypy/build/bot2/pypybuildbot Message-ID: <20081008114504.4F8E2169E55@codespeak.net> Author: pedronis Date: Wed Oct 8 13:45:03 2008 New Revision: 58803 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: halt on failures of translation Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Wed Oct 8 13:45:03 2008 @@ -39,6 +39,7 @@ command = ["python", "translate.py", "--batch"] translationTarget = "targetpypystandalone" + haltOnFailure = True def __init__(self, translationArgs, targetArgs, workdir="build/pypy/translator/goal", From arigo at codespeak.net Wed Oct 8 13:46:21 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 13:46:21 +0200 (CEST) Subject: [pypy-svn] r58804 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081008114621.40EBD169E82@codespeak.net> Author: arigo Date: Wed Oct 8 13:46:20 2008 New Revision: 58804 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py Log: (fijal, arigo) More shuffling. Trying to minimize the size of the diff for semispace.py. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py Wed Oct 8 13:46:20 2008 @@ -66,6 +66,23 @@ def size_gc_header(self, typeid=0): return self.gcheaderbuilder.size_gc_header + def header(self, addr): + addr -= self.gcheaderbuilder.size_gc_header + return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) + + def get_size(self, obj): + typeid = self.get_type_id(obj) + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + lenaddr = obj + self.varsize_offset_to_length(typeid) + length = lenaddr.signed[0] + size += length * self.varsize_item_sizes(typeid) + size = llarena.round_up_for_allocation(size) + # XXX maybe we should parametrize round_up_for_allocation() + # per GC; if we do, we also need to fix the call in + # gctypelayout.encode_type_shape() + return size + def malloc(self, typeid, length=0, zero=False): """For testing. The interface used by the gctransformer is the four malloc_[fixed,var]size[_clear]() functions. @@ -193,19 +210,6 @@ def debug_check_object(self, obj): pass - def get_size(self, obj): - typeid = self.get_type_id(obj) - size = self.fixed_size(typeid) - if self.is_varsize(typeid): - lenaddr = obj + self.varsize_offset_to_length(typeid) - length = lenaddr.signed[0] - size += length * self.varsize_item_sizes(typeid) - size = llarena.round_up_for_allocation(size) - # XXX maybe we should parametrize round_up_for_allocation() - # per GC; if we do, we also need to fix the call in - # gctypelayout.encode_type_shape() - return size - def execute_finalizers(self): self.finalizer_lock_count += 1 try: @@ -219,6 +223,7 @@ finally: self.finalizer_lock_count -= 1 + class MovingGCBase(GCBase): moving_gc = True @@ -231,14 +236,6 @@ def can_move(self, addr): return True - def header(self, addr): - addr -= self.gcheaderbuilder.size_gc_header - return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) - - def init_gc_object(self, addr, typeid, flags=0): - hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) - hdr.tid = typeid | flags - def id(self, ptr): # Default implementation for id(), assuming that "external" objects # never move. Overriden in the HybridGC. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 8 13:46:20 2008 @@ -64,8 +64,8 @@ first_unused_gcflag = first_gcflag << 2 def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096): - self.space_size = space_size MovingGCBase.__init__(self, chunk_size) + self.space_size = space_size self.red_zone = 0 def setup(self): Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/semispace.py Wed Oct 8 13:46:20 2008 @@ -13,8 +13,6 @@ import sys, os -DEBUG_PRINT = False -memoryError = MemoryError() TYPEID_MASK = 0xffff first_gcflag = 1 << 16 GCFLAG_FORWARDED = first_gcflag @@ -23,13 +21,15 @@ GCFLAG_EXTERNAL = first_gcflag << 1 GCFLAG_FINALIZATION_ORDERING = first_gcflag << 2 +DEBUG_PRINT = False +memoryError = MemoryError() + class SemiSpaceGC(MovingGCBase): _alloc_flavor_ = "raw" inline_simple_malloc = True inline_simple_malloc_varsize = True malloc_zero_filled = True first_unused_gcflag = first_gcflag << 3 - total_collection_time = 0.0 total_collection_count = 0 @@ -63,22 +63,6 @@ self.objects_with_finalizers = self.AddressDeque() self.objects_with_weakrefs = self.AddressStack() - def init_gc_object_immortal(self, addr, typeid, flags=0): - hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) - hdr.tid = typeid | flags | GCFLAG_EXTERNAL | GCFLAG_FORWARDED - # immortal objects always have GCFLAG_FORWARDED set; - # see get_forwarding_address(). - - def get_type_id(self, addr): - tid = self.header(addr).tid - ll_assert(tid & (GCFLAG_FORWARDED|GCFLAG_EXTERNAL) != GCFLAG_FORWARDED, - "get_type_id on forwarded obj") - # Non-prebuilt forwarded objects are overwritten with a FORWARDSTUB. - # Although calling get_type_id() on a forwarded object works by itself, - # we catch it as an error because it's likely that what is then - # done with the typeid is bogus. - return tid & TYPEID_MASK - # This class only defines the malloc_{fixed,var}size_clear() methods # because the spaces are filled with zeroes in advance. @@ -395,6 +379,26 @@ stub = llmemory.cast_adr_to_ptr(obj, self.FORWARDSTUBPTR) stub.forw = newobj + def get_type_id(self, addr): + tid = self.header(addr).tid + ll_assert(tid & (GCFLAG_FORWARDED|GCFLAG_EXTERNAL) != GCFLAG_FORWARDED, + "get_type_id on forwarded obj") + # Non-prebuilt forwarded objects are overwritten with a FORWARDSTUB. + # Although calling get_type_id() on a forwarded object works by itself, + # we catch it as an error because it's likely that what is then + # done with the typeid is bogus. + return tid & TYPEID_MASK + + def init_gc_object(self, addr, typeid, flags=0): + hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) + hdr.tid = typeid | flags + + def init_gc_object_immortal(self, addr, typeid, flags=0): + hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) + hdr.tid = typeid | flags | GCFLAG_EXTERNAL | GCFLAG_FORWARDED + # immortal objects always have GCFLAG_FORWARDED set; + # see get_forwarding_address(). + def deal_with_objects_with_finalizers(self, scan): # walk over list of objects with finalizers # if it is not copied, add it to the list of to-be-called finalizers @@ -553,4 +557,3 @@ STATISTICS_NUMBERS = 0 - From fijal at codespeak.net Wed Oct 8 13:46:45 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 8 Oct 2008 13:46:45 +0200 (CEST) Subject: [pypy-svn] r58805 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081008114645.29C01169E82@codespeak.net> Author: fijal Date: Wed Oct 8 13:46:44 2008 New Revision: 58805 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: (fijal, arigo) Reset arena for debugging Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 8 13:46:44 2008 @@ -331,8 +331,9 @@ objsize = self.get_size(obj) totalsize = size_gc_header + objsize if not self.surviving(obj): - # this object dies - pass + # this object dies. Following line is a noop in C, + # we clear it to make debugging easier + llarena.arena_reset(fromaddr, totalsize, False) else: ll_assert(self.is_forwarded(obj), "not forwarded, surviving obj") forward_ptr = hdr.forward_ptr From iko at codespeak.net Wed Oct 8 13:49:07 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Wed, 8 Oct 2008 13:49:07 +0200 (CEST) Subject: [pypy-svn] r58806 - in pypy/branch/2.5-merge: lib-python/modified-2.5.2/test pypy/objspace/std pypy/objspace/std/test Message-ID: <20081008114907.71EB8169EC8@codespeak.net> Author: iko Date: Wed Oct 8 13:49:06 2008 New Revision: 58806 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_set.py pypy/branch/2.5-merge/pypy/objspace/std/dictmultiobject.py pypy/branch/2.5-merge/pypy/objspace/std/dictobject.py pypy/branch/2.5-merge/pypy/objspace/std/frozensettype.py pypy/branch/2.5-merge/pypy/objspace/std/objspace.py pypy/branch/2.5-merge/pypy/objspace/std/setobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_dictobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Log: (iko,cfbolz) Fix various bugs in set found by std lib tests Be more careful when raising KeyErrors to prevent normalization from breaking on tuples Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_set.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_set.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_set.py Wed Oct 8 13:49:06 2008 @@ -278,6 +278,7 @@ fo.close() os.remove(test_support.TESTFN) + @test_support.impl_detail def test_do_not_rehash_dict_keys(self): n = 10 d = dict.fromkeys(map(HashCountingInt, xrange(n))) @@ -514,6 +515,7 @@ s.__init__(self.otherword) self.assertEqual(s, set(self.word)) + @test_support.impl_detail def test_singleton_empty_frozenset(self): f = frozenset() efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''), @@ -683,8 +685,12 @@ for v in self.set: self.assert_(v in self.values) setiter = iter(self.set) + + @test_support.impl_detail + def test__length_hint(self): # note: __length_hint__ is an internal undocumented API, # don't rely on it in your own programs + setiter = iter(self.set) self.assertEqual(setiter.__length_hint__(), len(self.set)) def test_pickling(self): Modified: pypy/branch/2.5-merge/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/dictmultiobject.py Wed Oct 8 13:49:06 2008 @@ -1124,7 +1124,7 @@ if w_missing_item is not None: return w_missing_item - raise OperationError(space.w_KeyError, w_lookup) + space.raise_key_error(w_lookup) def setitem__DictMulti_ANY_ANY(space, w_dict, w_newkey, w_newvalue): w_dict.implementation = w_dict.implementation.setitem(w_newkey, w_newvalue) @@ -1133,7 +1133,7 @@ try: w_dict.implementation = w_dict.implementation.delitem(w_lookup) except KeyError: - raise OperationError(space.w_KeyError, w_lookup) + space.raise_key_error(w_lookup) def len__DictMulti(space, w_dict): return space.wrap(w_dict.implementation.length()) @@ -1253,7 +1253,7 @@ if len_defaults > 0: return defaults[0] else: - raise OperationError(space.w_KeyError, w_key) + space.raise_key_error(w_key) else: w_dict.implementation.delitem(w_key) return w_item Modified: pypy/branch/2.5-merge/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/dictobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/dictobject.py Wed Oct 8 13:49:06 2008 @@ -78,7 +78,7 @@ except KeyError: w_missing_item = w_dict.missing_method(space, w_lookup) if w_missing_item is None: - raise OperationError(space.w_KeyError, w_lookup) + space.raise_key_error(w_lookup) else: return w_missing_item @@ -89,7 +89,7 @@ try: del w_dict.content[w_lookup] except KeyError: - raise OperationError(space.w_KeyError, w_lookup) + space.raise_key_error(w_lookup) def len__Dict(space, w_dict): return space.wrap(len(w_dict.content)) Modified: pypy/branch/2.5-merge/pypy/objspace/std/frozensettype.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/frozensettype.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/frozensettype.py Wed Oct 8 13:49:06 2008 @@ -40,7 +40,8 @@ def descr__frozenset__new__(space, w_frozensettype, w_iterable=NoneNotWrapped): from pypy.objspace.std.setobject import W_FrozensetObject from pypy.objspace.std.setobject import _is_frozenset_exact - if _is_frozenset_exact(w_iterable): + if (space.is_w(w_frozensettype, space.w_frozenset) and + _is_frozenset_exact(w_iterable)): return w_iterable w_obj = space.allocate_instance(W_FrozensetObject, w_frozensettype) W_FrozensetObject.__init__(w_obj, space, None) Modified: pypy/branch/2.5-merge/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/objspace.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/objspace.py Wed Oct 8 13:49:06 2008 @@ -791,6 +791,10 @@ else: ObjSpace.delslice(self, w_obj, w_start, w_stop) + def raise_key_error(self, w_key): + e = self.call_function(self.w_KeyError, w_key) + raise OperationError(self.w_KeyError, e) + class MM: "Container for multimethods." call = StdObjSpaceMultiMethod('call', 1, ['__call__'], general__args__=True) Modified: pypy/branch/2.5-merge/pypy/objspace/std/setobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/setobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/setobject.py Wed Oct 8 13:49:06 2008 @@ -313,14 +313,11 @@ try: return space.newbool(w_other in w_left.setdata) except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - - w_f = _convert_set_to_frozenset(space, w_other) - if w_f is not None: - return space.newbool(w_f in w_left.setdata) - else: - return space.w_False + if e.match(space, space.w_TypeError): + w_f = _convert_set_to_frozenset(space, w_other) + if w_f is not None: + return space.newbool(w_f in w_left.setdata) + raise contains__Frozenset_ANY = contains__Set_ANY @@ -437,10 +434,10 @@ except OperationError, e: if not e.match(space, space.w_TypeError): raise + w_f = _convert_set_to_frozenset(space, w_item) + if w_f is None: + raise - w_f = _convert_set_to_frozenset(space, w_item) - if w_f is None: - return w_item try: del w_left.setdata[w_f] return None @@ -457,7 +454,7 @@ def set_remove__Set_ANY(space, w_left, w_item): w_f = _discard_from_set(space, w_left, w_item) if w_f is not None: - raise OperationError(space.w_KeyError, w_f) + space.raise_key_error(w_f) def hash__Frozenset(space, w_set): multi = r_uint(1822399083) + r_uint(1822399083) + 1 @@ -633,7 +630,7 @@ 'The app-level part of repr().' set_id = id(s) if set_id in currently_in_repr: - return 'set(...)' + return '%s(...)' % (s.__class__.__name__,) currently_in_repr[set_id] = 1 try: return '%s(%s)' % (s.__class__.__name__, [x for x in s]) @@ -653,6 +650,8 @@ w_currently_in_repr = ec._py_repr = space.newdict() return setrepr(space, w_currently_in_repr, w_set) +repr__Frozenset = repr__Set + app = gateway.applevel(""" def reduce__Set(s): dict = getattr(s,'__dict__', None) @@ -660,8 +659,6 @@ """, filename=__file__) -repr__Frozenset = app.interphook('repr__Set') - set_reduce__Set = app.interphook('reduce__Set') frozenset_reduce__Frozenset = app.interphook('reduce__Set') Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_dictobject.py Wed Oct 8 13:49:06 2008 @@ -417,6 +417,39 @@ d1.update(d2) assert d1['a'] == 42 # fails on CPython, d1['a'] == 'foo' + def test_index_keyerror_unpacking(self): + d = {} + for v1 in ['Q', (1,)]: + try: + d[v1] + except KeyError, e: + v2 = e.args[0] + assert v1 == v2 + else: + assert False, 'Expected KeyError' + + def test_del_keyerror_unpacking(self): + d = {} + for v1 in ['Q', (1,)]: + try: + del d[v1] + except KeyError, e: + v2 = e.args[0] + assert v1 == v2 + else: + assert False, 'Expected KeyError' + + def test_pop_keyerror_unpacking(self): + d = {} + for v1 in ['Q', (1,)]: + try: + d.pop(v1) + except KeyError, e: + v2 = e.args[0] + assert v1 == v2 + else: + assert False, 'Expected KeyError' + # the minimal 'space' needed to use a W_DictObject class FakeSpace: Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_set.py Wed Oct 8 13:49:06 2008 @@ -83,6 +83,15 @@ s.add(A(s)) assert repr(s) == "set([1, 2, 3, set(...)])" + def test_recursive_repr_frozenset(self): + class A(object): + def __repr__(self): + return repr(self.s) + a = A() + s = frozenset([1, 2, 3, a]) + a.s = s + assert repr(s) == "frozenset([1, 2, 3, frozenset(...)])" + def test_keyerror_has_key(self): s = set() try: @@ -143,3 +152,44 @@ except KeyError, e: assert isinstance(e.args[0], frozenset) assert e.args[0] == frozenset([2, 3]) + + def test_contains(self): + letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + word = 'teleledningsanka' + s = set(word) + for c in letters: + assert (c in s) == (c in word) + raises(TypeError, s.__contains__, []) + + def test_remove(self): + s = set('abc') + s.remove('a') + assert 'a' not in s + raises(KeyError, s.remove, 'a') + raises(TypeError, s.remove, []) + s.add(frozenset('def')) + assert set('def') in s + s.remove(set('def')) + assert set('def') not in s + raises(KeyError, s.remove, set('def')) + + def test_remove_keyerror_unpacking(self): + # bug: www.python.org/sf/1576657 + s = set() + for v1 in ['Q', (1,)]: + try: + s.remove(v1) + except KeyError, e: + v2 = e.args[0] + assert v1 == v2 + else: + assert False, 'Expected KeyError' + + def test_singleton_empty_frozenset(self): + class Frozenset(frozenset): + pass + f = frozenset() + F = Frozenset() + efs = [f, Frozenset(f)] + # All empty frozenset subclass instances should have different ids + assert len(set(map(id, efs))) == len(efs) From arigo at codespeak.net Wed Oct 8 13:49:55 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 13:49:55 +0200 (CEST) Subject: [pypy-svn] r58807 - pypy/branch/gc-experiments/pypy/rpython/memory/test Message-ID: <20081008114955.9A7DC169EC8@codespeak.net> Author: arigo Date: Wed Oct 8 13:49:55 2008 New Revision: 58807 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Log: This test just passes, now that the hacks in MovingGCBase.id() have been killed long ago. Modified: pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/test/test_gc.py Wed Oct 8 13:49:55 2008 @@ -263,10 +263,6 @@ assert res def test_id(self): - py.test.skip("the MovingGCBase.id() logic can't be directly run") - # XXX ^^^ the problem is that the MovingGCBase instance holds - # references to GC objects - a list of weakrefs and a dict - and - # there is no way we can return these from get_roots_from_llinterp(). class A(object): pass a1 = A() From arigo at codespeak.net Wed Oct 8 13:51:32 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 13:51:32 +0200 (CEST) Subject: [pypy-svn] r58808 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081008115132.04299169E83@codespeak.net> Author: arigo Date: Wed Oct 8 13:51:32 2008 New Revision: 58808 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py Log: (fijal, arigo) Move this initialization to the run-time setup(). Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py Wed Oct 8 13:51:32 2008 @@ -227,8 +227,8 @@ class MovingGCBase(GCBase): moving_gc = True - def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE): - GCBase.__init__(self, chunk_size) + def setup(self): + GCBase.setup(self) self.objects_with_id = self.AddressDict() self.id_free_list = self.AddressStack() self.next_free_id = 1 From arigo at codespeak.net Wed Oct 8 14:03:24 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 14:03:24 +0200 (CEST) Subject: [pypy-svn] r58809 - pypy/branch/gc-experiments/pypy/rpython/memory/gc Message-ID: <20081008120324.29838169ECB@codespeak.net> Author: arigo Date: Wed Oct 8 14:03:23 2008 New Revision: 58809 Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Log: (fijal, arigo) Optimize get_forwarding_address(). Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Wed Oct 8 14:03:23 2008 @@ -85,9 +85,8 @@ def init_gc_object_immortal(self, addr, typeid, flags=0): hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) hdr.tid = typeid | flags | GCFLAG_EXTERNAL - hdr.forward_ptr = NULL - # immortal objects always have GCFLAG_FORWARDED set; - # see get_forwarding_address(). + hdr.forward_ptr = addr # so that get_forwarding_address(obj) returns + # obj itself if obj is a prebuilt object def malloc_fixedsize_clear(self, typeid, size, can_collect, has_finalizer=False, contains_weakptr=False): @@ -309,10 +308,7 @@ return self.header(obj).tid & GCFLAG_EXTERNAL def get_forwarding_address(self, obj): - if self._is_external(obj): - return obj - else: - return self.header(obj).forward_ptr + self.size_gc_header() + return self.header(obj).forward_ptr + self.size_gc_header() def set_forwarding_address(self, obj, newaddr): self.header(obj).forward_ptr = newaddr From jlg at codespeak.net Wed Oct 8 14:10:04 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Wed, 8 Oct 2008 14:10:04 +0200 (CEST) Subject: [pypy-svn] r58810 - in pypy/branch/2.5-merge/pypy/module/_file: . test Message-ID: <20081008121004.BF67A169EF8@codespeak.net> Author: jlg Date: Wed Oct 8 14:10:01 2008 New Revision: 58810 Modified: pypy/branch/2.5-merge/pypy/module/_file/interp_file.py pypy/branch/2.5-merge/pypy/module/_file/test/test_file_extra.py Log: __enter__() on a closed file raises ValueError - test and fix Modified: pypy/branch/2.5-merge/pypy/module/_file/interp_file.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_file/interp_file.py (original) +++ pypy/branch/2.5-merge/pypy/module/_file/interp_file.py Wed Oct 8 14:10:01 2008 @@ -86,6 +86,10 @@ self.fdopenstream(stream, fd, mode, name) def direct___enter__(self): + if self.stream is None: + space = self.space + raise OperationError(space.w_ValueError, + space.wrap('I/O operation on closed file')) return self def direct___exit__(self, __args__): Modified: pypy/branch/2.5-merge/pypy/module/_file/test/test_file_extra.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_file/test/test_file_extra.py (original) +++ pypy/branch/2.5-merge/pypy/module/_file/test/test_file_extra.py Wed Oct 8 14:10:01 2008 @@ -561,6 +561,7 @@ raises(ValueError, f.writelines, []) raises(ValueError, iter, f) raises(ValueError, f.xreadlines) + raises(ValueError, f.__enter__) f.close() # accepted as a no-op def test_docstrings(self): From arigo at codespeak.net Wed Oct 8 14:10:37 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 14:10:37 +0200 (CEST) Subject: [pypy-svn] r58811 - in pypy/dist/pypy: config rpython rpython/lltypesystem rpython/lltypesystem/test rpython/memory/gc rpython/memory/gc/test rpython/memory/test translator/c/src translator/c/test Message-ID: <20081008121037.C65A5169F0E@codespeak.net> Author: arigo Date: Wed Oct 8 14:10:36 2008 New Revision: 58811 Added: pypy/dist/pypy/rpython/memory/gc/markcompact.py - copied unchanged from r58809, pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Modified: pypy/dist/pypy/config/translationoption.py pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/lltypesystem/llarena.py pypy/dist/pypy/rpython/lltypesystem/llmemory.py pypy/dist/pypy/rpython/lltypesystem/lloperation.py pypy/dist/pypy/rpython/lltypesystem/test/test_llarena.py pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py pypy/dist/pypy/rpython/memory/gc/base.py pypy/dist/pypy/rpython/memory/gc/hybrid.py pypy/dist/pypy/rpython/memory/gc/marksweep.py pypy/dist/pypy/rpython/memory/gc/semispace.py pypy/dist/pypy/rpython/memory/gc/test/test_direct.py pypy/dist/pypy/rpython/memory/test/test_gc.py pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py pypy/dist/pypy/translator/c/src/mem.h pypy/dist/pypy/translator/c/test/test_lladdresses.py pypy/dist/pypy/translator/c/test/test_newgc.py Log: (fijal, arigo) Merge the gc-experiments branch, adding the markcompact gc. svn merge svn+ssh://codespeak.net/svn/pypy/dist at 58225 \ svn+ssh://codespeak.net/svn/pypy/branch/gc-experiments Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Wed Oct 8 14:10:36 2008 @@ -45,7 +45,7 @@ # gc ChoiceOption("gc", "Garbage Collection Strategy", ["boehm", "ref", "marksweep", "semispace", "statistics", - "generation", "hybrid", "none"], + "generation", "hybrid", "markcompact", "none"], "ref", requires={ "ref": [("translation.rweakref", False), # XXX ("translation.gctransformer", "ref")], @@ -57,6 +57,7 @@ "generation": [("translation.gctransformer", "framework")], "hybrid": [("translation.gctransformer", "framework")], "boehm": [("translation.gctransformer", "boehm")], + "markcompact": [("translation.gctransformer", "framework")], }, cmdline="--gc"), ChoiceOption("gctransformer", "GC transformer that is used - internal", @@ -299,7 +300,7 @@ '0': 'boehm nobackendopt', '1': 'boehm lowinline', 'size': 'boehm lowinline remove_asserts', - 'mem': 'generation lowinline remove_asserts', + 'mem': 'markcompact lowinline remove_asserts', '2': 'hybrid extraopts', '3': 'hybrid extraopts remove_asserts', } Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Wed Oct 8 14:10:36 2008 @@ -895,6 +895,8 @@ checkadr(toaddr) llmemory.raw_memcopy(fromaddr, toaddr, size) + op_raw_memmove = op_raw_memcopy # this is essentially the same here + def op_raw_load(self, addr, typ, offset): checkadr(addr) value = getattr(addr, str(typ).lower())[offset] Modified: pypy/dist/pypy/rpython/lltypesystem/llarena.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/llarena.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/llarena.py Wed Oct 8 14:10:36 2008 @@ -264,6 +264,9 @@ # work with fakearenaaddresses on which arbitrary arithmetic is # possible even on top of the llinterpreter. +# arena_new_view(ptr) is a no-op when translated, returns fresh view +# on previous arena when run on top of llinterp + def arena_malloc(nbytes, zero): """Allocate and return a new arena, optionally zero-initialized.""" return Arena(nbytes, zero).getaddr(0) @@ -299,6 +302,11 @@ following an object. For arenas containing heterogenous objects.""" return RoundedUpForAllocation(size) +def arena_new_view(ptr): + """Return a fresh memory view on an arena + """ + return Arena(ptr.arena.nbytes, False).getaddr(0) + # ____________________________________________________________ # # Translation support: the functions above turn into the code below. @@ -399,3 +407,9 @@ llimpl=llimpl_round_up_for_allocation, llfakeimpl=round_up_for_allocation, sandboxsafe=True) + +def llimpl_arena_new_view(addr): + return addr +register_external(arena_new_view, [llmemory.Address], llmemory.Address, + 'll_arena.arena_new_view', llimpl=llimpl_arena_new_view, + llfakeimpl=arena_new_view, sandboxsafe=True) Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py Wed Oct 8 14:10:36 2008 @@ -736,6 +736,12 @@ assert lltype.typeOf(dest) == Address size.raw_memcopy(source, dest) +def raw_memmove(source, dest, size): + # for now let's assume that raw_memmove is the same as raw_memcopy, + # when run on top of fake addresses, but we _free the source object + raw_memcopy(source, dest, size) + source.ptr._as_obj()._free() + def cast_any_ptr(EXPECTED_TYPE, ptr): # this is a generalization of the various cast_xxx_ptr() functions. PTRTYPE = lltype.typeOf(ptr) @@ -785,3 +791,19 @@ setattr(dest._obj, name, llvalue) else: raise TypeError(T) + +from pypy.rpython.extregistry import ExtRegistryEntry + +class RawMemmoveEntry(ExtRegistryEntry): + _about_ = raw_memmove + + def compute_result_annotation(self, s_from, s_to, s_size): + from pypy.annotation.model import SomeAddress, SomeInteger + assert isinstance(s_from, SomeAddress) + assert isinstance(s_to, SomeAddress) + assert isinstance(s_size, SomeInteger) + + def specialize_call(self, hop): + hop.exception_cannot_occur() + v_list = hop.inputargs(Address, Address, lltype.Signed) + return hop.genop('raw_memmove', v_list) Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Wed Oct 8 14:10:36 2008 @@ -368,6 +368,7 @@ 'raw_free': LLOp(), 'raw_memclear': LLOp(), 'raw_memcopy': LLOp(), + 'raw_memmove': LLOp(), 'raw_load': LLOp(sideeffects=False), 'raw_store': LLOp(), 'stack_malloc': LLOp(), # mmh Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_llarena.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_llarena.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_llarena.py Wed Oct 8 14:10:36 2008 @@ -4,7 +4,7 @@ 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 +from pypy.rpython.lltypesystem.llarena import ArenaError, arena_new_view def test_arena(): S = lltype.Struct('S', ('x',lltype.Signed)) @@ -150,6 +150,13 @@ arena_free(a) return 42 +def test_arena_new_view(): + a = arena_malloc(50, False) + arena_reserve(a, precomputed_size) + # we can now allocate the same space in new view + b = arena_new_view(a) + arena_reserve(b, precomputed_size) + def test_partial_arena_reset(): a = arena_malloc(50, False) def reserve(i): Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py Wed Oct 8 14:10:36 2008 @@ -504,6 +504,18 @@ raw_memcopy(at1, at2, sizeof(T)) assert t2.x == 1 +def test_raw_memmove(): + T = lltype.GcStruct('T', ('x', lltype.Signed)) + t1 = lltype.malloc(T) + t2 = lltype.malloc(T) + t1.x = 1 + t2.x = 2 + at1 = cast_ptr_to_adr(t1) + at2 = cast_ptr_to_adr(t2) + raw_memmove(at1, at2, sizeof(T)) + assert t2.x == 1 + py.test.raises(RuntimeError, "t1.x") + def test_raw_memcopy_nonrec(): T = lltype.GcStruct('T', ('x', lltype.Signed)) A = lltype.FixedSizeArray(lltype.Ptr(T), 1) Modified: pypy/dist/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/base.py (original) +++ pypy/dist/pypy/rpython/memory/gc/base.py Wed Oct 8 14:10:36 2008 @@ -1,5 +1,10 @@ -from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem import lltype, llmemory, llarena from pypy.rlib.debug import ll_assert +from pypy.rpython.memory.gcheader import GCHeaderBuilder +from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE +from pypy.rpython.memory.support import get_address_stack, get_address_deque +from pypy.rpython.memory.support import AddressDict +from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage class GCBase(object): _alloc_flavor_ = "raw" @@ -9,6 +14,13 @@ prebuilt_gc_objects_are_static_roots = True can_realloc = False + def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE): + self.gcheaderbuilder = GCHeaderBuilder(self.HDR) + self.AddressStack = get_address_stack(chunk_size) + self.AddressDeque = get_address_deque(chunk_size) + self.AddressDict = AddressDict + self.finalizer_lock_count = 0 + def can_malloc_nonmovable(self): return not self.moving_gc @@ -46,7 +58,7 @@ pass def setup(self): - pass + self.run_finalizers = self.AddressDeque() def statistics(self, index): return -1 @@ -54,6 +66,23 @@ def size_gc_header(self, typeid=0): return self.gcheaderbuilder.size_gc_header + def header(self, addr): + addr -= self.gcheaderbuilder.size_gc_header + return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) + + def get_size(self, obj): + typeid = self.get_type_id(obj) + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + lenaddr = obj + self.varsize_offset_to_length(typeid) + length = lenaddr.signed[0] + size += length * self.varsize_item_sizes(typeid) + size = llarena.round_up_for_allocation(size) + # XXX maybe we should parametrize round_up_for_allocation() + # per GC; if we do, we also need to fix the call in + # gctypelayout.encode_type_shape() + return size + def malloc(self, typeid, length=0, zero=False): """For testing. The interface used by the gctransformer is the four malloc_[fixed,var]size[_clear]() functions. @@ -181,13 +210,86 @@ def debug_check_object(self, obj): pass + def execute_finalizers(self): + self.finalizer_lock_count += 1 + try: + while self.run_finalizers.non_empty(): + if self.finalizer_lock_count > 1: + # the outer invocation of execute_finalizers() will do it + break + obj = self.run_finalizers.popleft() + finalizer = self.getfinalizer(self.get_type_id(obj)) + finalizer(obj) + finally: + self.finalizer_lock_count -= 1 + class MovingGCBase(GCBase): moving_gc = True + def setup(self): + GCBase.setup(self) + self.objects_with_id = self.AddressDict() + self.id_free_list = self.AddressStack() + self.next_free_id = 1 + def can_move(self, addr): return True + def id(self, ptr): + # Default implementation for id(), assuming that "external" objects + # never move. Overriden in the HybridGC. + obj = llmemory.cast_ptr_to_adr(ptr) + if self._is_external(obj): + result = obj + else: + result = self._compute_id(obj) + return llmemory.cast_adr_to_int(result) + + def _next_id(self): + # return an id not currently in use (as an address instead of an int) + if self.id_free_list.non_empty(): + result = self.id_free_list.pop() # reuse a dead id + else: + # make up a fresh id number + result = llmemory.cast_int_to_adr(self.next_free_id) + self.next_free_id += 2 # only odd numbers, to make lltype + # and llmemory happy and to avoid + # clashes with real addresses + return result + + def _compute_id(self, obj): + # look if the object is listed in objects_with_id + result = self.objects_with_id.get(obj) + if not result: + result = self._next_id() + self.objects_with_id.setitem(obj, result) + return result + + def update_objects_with_id(self): + old = self.objects_with_id + new_objects_with_id = self.AddressDict(old.length()) + old.foreach(self._update_object_id_FAST, new_objects_with_id) + old.delete() + self.objects_with_id = new_objects_with_id + + def _update_object_id(self, obj, id, new_objects_with_id): + # safe version (used by subclasses) + if self.surviving(obj): + newobj = self.get_forwarding_address(obj) + new_objects_with_id.setitem(newobj, id) + else: + self.id_free_list.append(id) + + def _update_object_id_FAST(self, obj, id, new_objects_with_id): + # unsafe version, assumes that the new_objects_with_id is large enough + if self.surviving(obj): + newobj = self.get_forwarding_address(obj) + new_objects_with_id.insertclean(newobj, id) + else: + self.id_free_list.append(id) + + def choose_gc_from_config(config): """Return a (GCClass, GC_PARAMS) from the given config object. """ @@ -199,6 +301,7 @@ "semispace": "semispace.SemiSpaceGC", "generation": "generation.GenerationGC", "hybrid": "hybrid.HybridGC", + "markcompact" : "markcompact.MarkCompactGC", } try: modulename, classname = classes[config.translation.gc].split('.') Modified: pypy/dist/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/dist/pypy/rpython/memory/gc/hybrid.py Wed Oct 8 14:10:36 2008 @@ -1,8 +1,8 @@ import sys from pypy.rpython.memory.gc.semispace import SemiSpaceGC from pypy.rpython.memory.gc.semispace import DEBUG_PRINT -from pypy.rpython.memory.gc.generation import GenerationGC, GCFLAG_FORWARDED -from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL +from pypy.rpython.memory.gc.generation import GenerationGC +from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED from pypy.rpython.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS from pypy.rpython.memory.gc.generation import GCFLAG_NO_HEAP_PTRS from pypy.rpython.lltypesystem import lltype, llmemory, llarena @@ -550,19 +550,23 @@ dead_size, "bytes in", dead_count, "objs") - def _compute_id_for_external(self, obj): - # the base classes make the assumption that all external objects - # have an id equal to their address. This is wrong if the object - # is a generation 3 rawmalloced object that initially lived in - # the semispaces. - if self.is_last_generation(obj): - # in this case, we still need to check if the object had its - # id taken before. If not, we can use its address as its id. - return self.objects_with_id.get(obj, obj) - else: - # a generation 2 external object was never non-external in - # the past, so it cannot be listed in self.objects_with_id. - return obj + def id(self, ptr): + obj = llmemory.cast_ptr_to_adr(ptr) + if self._is_external(obj): + # a prebuilt or rawmalloced object + if self.is_last_generation(obj): + # a generation 3 object may be one that used to live in + # the semispace. So we still need to check if the object had + # its id taken before. If not, we can use its address as its + # id as it is not going to move any more. + result = self.objects_with_id.get(obj, obj) + else: + # a generation 2 external object was never non-external in + # the past, so it cannot be listed in self.objects_with_id. + result = obj + else: + result = self._compute_id(obj) # common case + return llmemory.cast_adr_to_int(result) # XXX a possible optimization would be to use three dicts, one # for each generation, instead of mixing gen2 and gen3 objects. Modified: pypy/dist/pypy/rpython/memory/gc/marksweep.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/marksweep.py (original) +++ pypy/dist/pypy/rpython/memory/gc/marksweep.py Wed Oct 8 14:10:36 2008 @@ -22,8 +22,6 @@ DEBUG_PRINT = False memoryError = MemoryError() class MarkSweepGC(GCBase): - _alloc_flavor_ = "raw" - HDR = lltype.ForwardReference() HDRPTR = lltype.Ptr(HDR) # need to maintain a linked list of malloced objects, since we used the @@ -44,17 +42,16 @@ TRANSLATION_PARAMS = {'start_heap_size': 8*1024*1024} # XXX adjust def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, start_heap_size=4096): + GCBase.__init__(self, chunk_size) self.heap_usage = 0 # at the end of the latest collection self.bytes_malloced = 0 # since the latest collection self.bytes_malloced_threshold = start_heap_size self.total_collection_time = 0.0 - self.AddressStack = get_address_stack(chunk_size) self.malloced_objects = lltype.nullptr(self.HDR) self.malloced_objects_with_finalizer = lltype.nullptr(self.HDR) # these are usually only the small bits of memory that make a # weakref object self.objects_with_weak_pointers = lltype.nullptr(self.HDR) - self.gcheaderbuilder = GCHeaderBuilder(self.HDR) # pools, for x_swap_pool(): # 'curpool' is the current pool, lazily allocated (i.e. NULL means # the current POOL object is not yet malloc'ed). POOL objects are Modified: pypy/dist/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/dist/pypy/rpython/memory/gc/semispace.py Wed Oct 8 14:10:36 2008 @@ -4,7 +4,6 @@ from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE from pypy.rpython.memory.support import get_address_stack, get_address_deque from pypy.rpython.memory.support import AddressDict -from pypy.rpython.memory.gcheader import GCHeaderBuilder from pypy.rpython.lltypesystem import lltype, llmemory, llarena from pypy.rlib.objectmodel import free_non_gc_object from pypy.rlib.debug import ll_assert @@ -45,17 +44,10 @@ def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096, max_space_size=sys.maxint//2+1): - MovingGCBase.__init__(self) + MovingGCBase.__init__(self, chunk_size) self.space_size = space_size self.max_space_size = max_space_size - self.gcheaderbuilder = GCHeaderBuilder(self.HDR) - self.AddressStack = get_address_stack(chunk_size) - self.AddressDeque = get_address_deque(chunk_size) - self.AddressDict = AddressDict - self.finalizer_lock_count = 0 self.red_zone = 0 - self.id_free_list = self.AddressStack() - self.next_free_id = 1 def setup(self): if DEBUG_PRINT: @@ -67,10 +59,9 @@ self.fromspace = llarena.arena_malloc(self.space_size, True) ll_assert(bool(self.fromspace), "couldn't allocate fromspace") self.free = self.tospace + MovingGCBase.setup(self) self.objects_with_finalizers = self.AddressDeque() - self.run_finalizers = self.AddressDeque() self.objects_with_weakrefs = self.AddressStack() - self.objects_with_id = self.AddressDict() # This class only defines the malloc_{fixed,var}size_clear() methods # because the spaces are filled with zeroes in advance. @@ -388,20 +379,6 @@ stub = llmemory.cast_adr_to_ptr(obj, self.FORWARDSTUBPTR) stub.forw = newobj - def get_size(self, obj): - typeid = self.get_type_id(obj) - size = self.fixed_size(typeid) - if self.is_varsize(typeid): - lenaddr = obj + self.varsize_offset_to_length(typeid) - length = lenaddr.signed[0] - size += length * self.varsize_item_sizes(typeid) - size = llarena.round_up_for_allocation(size) - return size - - def header(self, addr): - addr -= self.gcheaderbuilder.size_gc_header - return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) - def get_type_id(self, addr): tid = self.header(addr).tid ll_assert(tid & (GCFLAG_FORWARDED|GCFLAG_EXTERNAL) != GCFLAG_FORWARDED, @@ -556,75 +533,8 @@ self.run_finalizers.delete() self.run_finalizers = new_run_finalizer - def execute_finalizers(self): - self.finalizer_lock_count += 1 - try: - while self.run_finalizers.non_empty(): - #print "finalizer" - if self.finalizer_lock_count > 1: - # the outer invocation of execute_finalizers() will do it - break - obj = self.run_finalizers.popleft() - finalizer = self.getfinalizer(self.get_type_id(obj)) - finalizer(obj) - finally: - self.finalizer_lock_count -= 1 - - def id(self, ptr): - obj = llmemory.cast_ptr_to_adr(ptr) - if self.header(obj).tid & GCFLAG_EXTERNAL: - result = self._compute_id_for_external(obj) - else: - result = self._compute_id(obj) - return llmemory.cast_adr_to_int(result) - - def _next_id(self): - # return an id not currently in use (as an address instead of an int) - if self.id_free_list.non_empty(): - result = self.id_free_list.pop() # reuse a dead id - else: - # make up a fresh id number - result = llmemory.cast_int_to_adr(self.next_free_id) - self.next_free_id += 2 # only odd numbers, to make lltype - # and llmemory happy and to avoid - # clashes with real addresses - return result - - def _compute_id(self, obj): - # look if the object is listed in objects_with_id - result = self.objects_with_id.get(obj) - if not result: - result = self._next_id() - self.objects_with_id.setitem(obj, result) - return result - - def _compute_id_for_external(self, obj): - # For prebuilt objects, we can simply return their address. - # This method is overriden by the HybridGC. - return obj - - def update_objects_with_id(self): - old = self.objects_with_id - new_objects_with_id = self.AddressDict(old.length()) - old.foreach(self._update_object_id_FAST, new_objects_with_id) - old.delete() - self.objects_with_id = new_objects_with_id - - def _update_object_id(self, obj, id, new_objects_with_id): - # safe version (used by subclasses) - if self.surviving(obj): - newobj = self.get_forwarding_address(obj) - new_objects_with_id.setitem(newobj, id) - else: - self.id_free_list.append(id) - - def _update_object_id_FAST(self, obj, id, new_objects_with_id): - # unsafe version, assumes that the new_objects_with_id is large enough - if self.surviving(obj): - newobj = self.get_forwarding_address(obj) - new_objects_with_id.insertclean(newobj, id) - else: - self.id_free_list.append(id) + def _is_external(self, obj): + return (self.header(obj).tid & GCFLAG_EXTERNAL) != 0 def debug_check_object(self, obj): """Check the invariants about 'obj' that should be true Modified: pypy/dist/pypy/rpython/memory/gc/test/test_direct.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/test/test_direct.py (original) +++ pypy/dist/pypy/rpython/memory/gc/test/test_direct.py Wed Oct 8 14:10:36 2008 @@ -279,3 +279,7 @@ 'large_object_gcptrs': 12, 'generation3_collect_threshold': 5, } + +class TestMarkCompactGC(DirectGCTest): + from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass + Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Wed Oct 8 14:10:36 2008 @@ -9,7 +9,7 @@ from pypy.rpython.lltypesystem.rstr import STR from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.objectmodel import compute_unique_id +from pypy.rlib.objectmodel import compute_unique_id, keepalive_until_here def stdout_ignore_ll_functions(msg): @@ -263,10 +263,6 @@ assert res def test_id(self): - py.test.skip("the MovingGCBase.id() logic can't be directly run") - # XXX ^^^ the problem is that the MovingGCBase instance holds - # references to GC objects - a list of weakrefs and a dict - and - # there is no way we can return these from get_roots_from_llinterp(). class A(object): pass a1 = A() @@ -318,6 +314,44 @@ res = self.interpret(f, [500]) assert res == 1 + 500 + + def test_collect_during_collect(self): + class B(object): + pass + b = B() + b.nextid = 1 + b.num_deleted = 0 + b.num_deleted_c = 0 + class A(object): + def __init__(self): + self.id = b.nextid + b.nextid += 1 + def __del__(self): + llop.gc__collect(lltype.Void) + b.num_deleted += 1 + C() + C() + class C(A): + def __del__(self): + b.num_deleted += 1 + b.num_deleted_c += 1 + def f(x, y): + persistent_a1 = A() + persistent_a2 = A() + i = 0 + while i < x: + i += 1 + a = A() + persistent_a3 = A() + persistent_a4 = A() + llop.gc__collect(lltype.Void) + llop.gc__collect(lltype.Void) + b.bla = persistent_a1.id + persistent_a2.id + persistent_a3.id + persistent_a4.id + print b.num_deleted_c + return b.num_deleted + res = self.interpret(f, [4, 42]) + assert res == 12 + def test_weakref_across_minor_collection(self): import weakref class A: @@ -455,6 +489,15 @@ class TestGenerationalGC(TestSemiSpaceGC): from pypy.rpython.memory.gc.generation import GenerationGC as GCClass +class TestMarkCompactGC(TestSemiSpaceGC): + from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass + + def test_finalizer_order(self): + py.test.skip("Not implemented yet") + +class TestMarkCompactGCGrowing(TestMarkCompactGC): + GC_PARAMS = {'space_size': 64} + class TestHybridGC(TestGenerationalGC): from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass GC_CANNOT_MALLOC_NONMOVABLE = False Modified: pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py Wed Oct 8 14:10:36 2008 @@ -341,6 +341,7 @@ b = B() b.nextid = 1 b.num_deleted = 0 + b.num_deleted_c = 0 class A(object): def __init__(self): self.id = b.nextid @@ -353,6 +354,7 @@ class C(A): def __del__(self): b.num_deleted += 1 + b.num_deleted_c += 1 def f(x, y): persistent_a1 = A() persistent_a2 = A() @@ -365,6 +367,7 @@ llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) b.bla = persistent_a1.id + persistent_a2.id + persistent_a3.id + persistent_a4.id + print b.num_deleted_c return b.num_deleted run = self.runner(f, nbargs=2) # runs collect recursively 4 times @@ -798,6 +801,15 @@ GC_PARAMS = {'space_size': 2048} root_stack_depth = 200 +class TestMarkCompactGC(GenericMovingGCTests): + gcname = 'markcompact' + + class gcpolicy(gc.FrameworkGcPolicy): + class transformerclass(framework.FrameworkGCTransformer): + from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass + GC_PARAMS = {'space_size': 2048} + root_stack_depth = 200 + class TestGenerationGC(GenericMovingGCTests): gcname = "generation" Modified: pypy/dist/pypy/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/dist/pypy/translator/c/src/mem.h Wed Oct 8 14:10:36 2008 @@ -90,6 +90,7 @@ if (r != NULL) memset((void*) r, 0, size); #define OP_RAW_MEMCOPY(x,y,size,r) memcpy(y,x,size); +#define OP_RAW_MEMMOVE(x,y,size,r) memmove(y,x,size); /************************************************************/ Modified: pypy/dist/pypy/translator/c/test/test_lladdresses.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_lladdresses.py (original) +++ pypy/dist/pypy/translator/c/test/test_lladdresses.py Wed Oct 8 14:10:36 2008 @@ -96,6 +96,19 @@ res = fc() assert res +def test_raw_memmove(): + def f(): + addr = raw_malloc(100) + addr.signed[0] = 12 + (addr + 10).signed[0] = 42 + raw_memmove(addr, addr + 4, 96) + result = (addr + 4).signed[0] + (addr + 14).signed[0] + raw_free(addr) + return result + fc = compile(f, []) + res = fc() + assert res + def test_pointer_comparison(): def f(): result = 0 Modified: pypy/dist/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_newgc.py (original) +++ pypy/dist/pypy/translator/c/test/test_newgc.py Wed Oct 8 14:10:36 2008 @@ -1028,3 +1028,13 @@ def test_gc_set_max_heap_size(self): py.test.skip("not implemented") + +class TestMarkCompactGC(TestSemiSpaceGC): + gcpolicy = "markcompact" + should_be_moving = True + + def test_gc_set_max_heap_size(self): + py.test.skip("not implemented") + + def test_finalizer_order(self): + py.test.skip("not implemented") From arigo at codespeak.net Wed Oct 8 14:10:41 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 14:10:41 +0200 (CEST) Subject: [pypy-svn] r58812 - pypy/branch/gc-experiments Message-ID: <20081008121041.7296F169F16@codespeak.net> Author: arigo Date: Wed Oct 8 14:10:40 2008 New Revision: 58812 Removed: pypy/branch/gc-experiments/ Log: (fijal, arigo) Kill the merged branch. From iko at codespeak.net Wed Oct 8 14:11:51 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Wed, 8 Oct 2008 14:11:51 +0200 (CEST) Subject: [pypy-svn] r58813 - in pypy/branch/2.5-merge/pypy/lib: . app_test Message-ID: <20081008121151.6F46E169F0D@codespeak.net> Author: iko Date: Wed Oct 8 14:11:50 2008 New Revision: 58813 Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_datetime.py pypy/branch/2.5-merge/pypy/lib/datetime.py Log: (iko, cfbolz) Add strptime to datetime.datetime Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_datetime.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/app_test/test_datetime.py (original) +++ pypy/branch/2.5-merge/pypy/lib/app_test/test_datetime.py Wed Oct 8 14:11:50 2008 @@ -5,3 +5,13 @@ print datetime expected = "datetime.datetime(1, 2, 3, 0, 0)" assert repr(datetime.datetime(1,2,3)) == expected + +def test_strptime(): + import time + + string = '2004-12-01 13:02:47' + format = '%Y-%m-%d %H:%M:%S' + expected = datetime.datetime(*(time.strptime(string, format)[0:6])) + got = datetime.datetime.strptime(string, format) + assert expected == got + Modified: pypy/branch/2.5-merge/pypy/lib/datetime.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/datetime.py (original) +++ pypy/branch/2.5-merge/pypy/lib/datetime.py Wed Oct 8 14:11:50 2008 @@ -1576,6 +1576,11 @@ "Convert to string, for str()." return self.isoformat(sep=' ') + @classmethod + def strptime(cls, date_string, format): + 'string, format -> new datetime parsed from a string (like time.strptime()).' + return cls(*_time.strptime(date_string, format)[0:6]) + def utcoffset(self): """Return the timezone offset in minutes east of UTC (negative west of UTC).""" From witulski at codespeak.net Wed Oct 8 14:28:09 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Wed, 8 Oct 2008 14:28:09 +0200 (CEST) Subject: [pypy-svn] r58814 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081008122809.5A676169F49@codespeak.net> Author: witulski Date: Wed Oct 8 14:28:07 2008 New Revision: 58814 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py Log: (re)added Register and Stack classes for genVar locations Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Wed Oct 8 14:28:07 2008 @@ -1,4 +1,4 @@ -from pypy.jit.codegen.x86_64.objmodel import IntVar, Immediate8, Immediate32, Immediate64 +from pypy.jit.codegen.x86_64.objmodel import IntVar, Register8, Register64, Immediate8, Immediate32, Immediate64 # Mapping from 64Bit-Register to coding (Rex.W or Rex.B , ModRM) REGISTER_MAP = { @@ -45,10 +45,10 @@ rexB = B # TODO: other cases e.g memory as operand if isinstance(arg1,IntVar): - if arg1.location_type == "Register64": - rexB, modrm1 = self.get_register_bits(arg1.pos_str) - elif arg1.location_type == "Register8": - modrm1 = self.get_register_bits_8Bit(arg1.pos_str) + if isinstance(arg1.location, Register64): + rexB, modrm1 = self.get_register_bits(arg1.location.reg) + elif isinstance(arg1.location, Register8): + modrm1 = self.get_register_bits_8Bit(arg1.location.reg) # exchange the two arguments (modrm2/modrm1) if isinstance(arg2,Immediate32): @@ -66,8 +66,8 @@ self.write_modRM_byte(3, modrm2, modrm1) self.write(chr(arg2.value)) elif isinstance(arg2, IntVar): - if arg2.location_type == "Register64": - rexR, modrm2 = self.get_register_bits(arg2.pos_str) + if isinstance(arg2.location, Register64): + rexR, modrm2 = self.get_register_bits(arg2.location.reg) # FIXME: exchange the two arguments (rexB/rexR) self.write_rex_byte(rexW, rexR, rexX, rexB) self.write(opcode) @@ -96,10 +96,10 @@ # TODO: other cases e.g memory as operand if isinstance(arg1, IntVar): - if arg1.location_type == "Register64": - rexB, modrm1 = self.get_register_bits(arg1.pos_str) - elif arg1.location_type == "Register8": - modrm1 = self.get_register_bits_8Bit(arg1.pos_str) + if isinstance(arg1.location, Register64): + rexB, modrm1 = self.get_register_bits(arg1.location.reg) + elif isinstance(arg1.location, Register8): + modrm1 = self.get_register_bits_8Bit(arg1.location.reg) # rexW(1) = 64bitMode self.write_rex_byte(rexW, rexR, rexX, rexB) @@ -125,8 +125,8 @@ # TODO: other cases e.g memory as operand # FIXME: rexB? if isinstance(arg1, IntVar): - if arg1.location_type == "Register64": - rexB, modrm1 = self.get_register_bits(arg1.pos_str) + if isinstance(arg1.location, Register64): + rexB, modrm1 = self.get_register_bits(arg1.location.reg) if isinstance(arg2, Immediate64): new_opcode = hex(int(opcode,16)+modrm1) @@ -149,8 +149,8 @@ # TODO: other cases e.g memory as operand # FIXME: rexB? if isinstance(arg1, IntVar): - if arg1.location_type == "Register64": - rexB, modrm1 = self.get_register_bits(arg1.pos_str) + if isinstance(arg1.location, Register64): + rexB, modrm1 = self.get_register_bits(arg1.location.reg) new_opcode = hex(int(opcode,16)+modrm1) assert len(new_opcode[2:len(new_opcode)]) == 2 self.write_rex_byte(rexW, rexR, rexX, rexB) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py Wed Oct 8 14:28:07 2008 @@ -6,16 +6,29 @@ # The to_string method is used to choose the right # method inside the assembler +class Register64(object): + def __init__(self, reg): + self.reg = reg + +class Register8(object): + def __init__(self, reg): + self.reg = reg + +class Stack64(object): + def __init__(self, offset): + self.offset = offset + class IntVar(model.GenVar): - def __init__(self, pos_str, location_type): - self.pos_str = pos_str - self.location_type = location_type - assert location_type == "Register64" or location_type == "Register8" + def __init__(self, location): + self.location = location + assert isinstance(location, Register64) or isinstance(location, Register8) or isinstance(location, Stack64) def to_string(self): - if self.location_type=="Register8": + if isinstance(self.location, Stack64): + return "_STACK" + if isinstance(self.location, Register8): return "_8REG" - elif self.location_type=="Register64": + elif isinstance(self.location, Register64): return "_QWREG" class Immediate8(model.GenConst): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Wed Oct 8 14:28:07 2008 @@ -1,6 +1,6 @@ from pypy.jit.codegen import model from pypy.rlib.objectmodel import specialize -from pypy.jit.codegen.x86_64.objmodel import IntVar, Immediate8, Immediate32, Immediate64 +from pypy.jit.codegen.x86_64.objmodel import IntVar, Register64, Register8, Immediate8, Immediate32, Immediate64 from pypy.jit.codegen.x86_64.codebuf import InMemoryCodeBuilder #TODO: understand llTypesystem from pypy.rpython.lltypesystem import llmemory, lltype @@ -63,7 +63,7 @@ self.moves = [] def create_fresh_location(self): - return self.builder.allocate_register().pos_str + return self.builder.allocate_register().location.reg def emit_move(self, source, target): self.moves.append((source, target)) @@ -92,9 +92,9 @@ # "r14":None, # "r15":None, } - self.known_gv = [] + self.known_gv = [] # contains the live genvars (used for spilling and allocation) for reg in used_registers: - self.allocate_register(reg.pos_str) + del self.freeregisters[reg.location.reg] def _open(self): pass @@ -124,7 +124,7 @@ # TODO: support reg8 def op_cast_bool_to_int(self, gv_x): - assert isinstance(gv_x, IntVar) and gv_x.location_type == "Register64" + assert isinstance(gv_x, IntVar) and isinstance(gv_x.location,Register64) return gv_x # 0 xor 1 == 1 @@ -183,52 +183,53 @@ # choose rax,rcx or rdx # TODO: use also rcx rdx gv_z = self.allocate_register("rax") - self.mc.SETG(IntVar("al","Register8")) - return IntVar("rax", "Register64") + self.mc.SETG(IntVar(Register8("al"))) + return IntVar(Register64("rax")) def op_int_lt(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETL(IntVar("al","Register8")) - return IntVar("rax", "Register64") + self.mc.SETL(IntVar(Register8("al"))) + return IntVar(Register64("rax")) def op_int_le(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETLE(IntVar("al","Register8")) - return IntVar("rax", "Register64") + self.mc.SETLE(IntVar(Register8("al"))) + return IntVar(Register64("rax")) def op_int_eq(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETE(IntVar("al","Register8")) - return IntVar("rax", "Register64") + self.mc.SETE(IntVar(Register8("al"))) + return IntVar(Register64("rax")) def op_int_ne(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETNE(IntVar("al","Register8")) - return IntVar("rax", "Register64") + self.mc.SETNE(IntVar(Register8("al"))) + return IntVar(Register64("rax")) def op_int_ge(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") - self.mc.SETGE(IntVar("al","Register8")) - return IntVar("rax", "Register64") + self.mc.SETGE(IntVar(Register8("al"))) + return IntVar(Register64("rax")) # the moves to pass arg. when making a jump to a block + #FIXME: problem with mapping of stackpositions def _compute_moves(self, outputargs_gv, targetargs_gv): tar2src = {} tar2loc = {} src2loc = {} for i in range(len(outputargs_gv)): - target_gv = targetargs_gv[i].pos_str - source_gv = outputargs_gv[i].pos_str + target_gv = targetargs_gv[i].location.reg + source_gv = outputargs_gv[i].location.reg tar2src[target_gv] = source_gv tar2loc[target_gv] = target_gv src2loc[source_gv] = source_gv movegen = MoveEmitter(self) - emit_moves(movegen, [target_gv.pos_str for target_gv in targetargs_gv], + emit_moves(movegen, [target_gv.location.reg for target_gv in targetargs_gv], tar2src, tar2loc, src2loc) return movegen.moves @@ -253,7 +254,7 @@ #self.mc.write("\xB8\x0F\x00\x00\x00") self._open() if not gv_returnvar == None:#check void return - self.mc.MOV(IntVar("rax", "Register64"), gv_returnvar) + self.mc.MOV(IntVar(Register64("rax")), gv_returnvar) self.mc.RET() self._close() @@ -268,35 +269,35 @@ #self.mc.JMP(gv_x) moves = self._compute_moves(outputargs_gv, target.arg_positions) for source_gv, target_gv in moves: - self.mc.MOV(IntVar(source_gv, "Register64"), IntVar(target_gv, "Register64")) + self.mc.MOV(IntVar(Register64(source_gv)),IntVar(Register64(target_gv))) self.mc.JMP(target.startaddr) self._close() - + # TODO: support the allocation of 8bit Reg def allocate_register(self, register=None): if register is None: if not self.freeregisters: - raise NotImplementedError("spilling not implemented") - - new_gv = IntVar((self.freeregisters.popitem()[0]), "Register64") + #raise NotImplementedError("spilling not implemented") + return self.spill_register() + new_gv = IntVar(Register64(self.freeregisters.popitem()[0])) self.known_gv.append(new_gv) return new_gv else: if register not in self.freeregisters: # the register must be in the list! for i in range(len(self.known_gv)): - if register == self.known_gv[i].pos_str: + if register == self.known_gv[i].location.reg: # move the values from the requiered register # to an other one and return the # requested one. gv = self.allocate_register() self.mc.MOV(gv,self.known_gv[i]) - new_gv = IntVar(register, "Register64") + new_gv = IntVar(Register64(register)) self.known_gv.append(new_gv) return new_gv raise NotImplementedError("register moves") del self.freeregisters[register] - new_gv = IntVar(register, "Register64") + new_gv = IntVar(Register64(register)) self.known_gv.append(new_gv) return new_gv @@ -316,6 +317,28 @@ def _close(self): self.mc.done() + + # TODO: alloc strategy + # TODO: support 8bit reg. alloc + # just greddy + def spill_register(self): + # take the first gv which is not + # on the stack + gv_to_spill = None + for i in range(len(known_gv)): + if not known_gv[i].location_type == "Stack64": + gv_to_spill = self.known_gv[i] + break + # there must be genVars which are + # inside an register so: + assert not gv_to_spill==None + + #TODO: update Stackposition + + self.mc.PUSH(gv_to_spill) + new_gv = IntVar(Register64(gv_to_spill.location.reg)) + gv_to_spill.location = Stack64(42) #XXX + return new_gv class RX86_64GenOp(model.AbstractRGenOp): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py Wed Oct 8 14:28:07 2008 @@ -1,5 +1,5 @@ from pypy.jit.codegen.x86_64 import assembler -from pypy.jit.codegen.x86_64.objmodel import IntVar, Immediate32 +from pypy.jit.codegen.x86_64.objmodel import IntVar, Register64, Immediate32 class AsmTest(assembler.X86_64CodeBuilder): def __init__(self): @@ -13,12 +13,12 @@ def test_add(): mc = AsmTest() - mc.ADD(IntVar("rax", "Register64"), IntVar("r11", "Register64")) + mc.ADD(IntVar(Register64("rax")), IntVar(Register64("r11"))) assert mc.get_as_string() == "\x4C\x01\xD8" - mc.ADD(IntVar("rbx", "Register64"), IntVar("rbx", "Register64")) + mc.ADD(IntVar(Register64("rbx")), IntVar(Register64("rbx"))) assert mc.get_as_string() == "\x4C\x01\xD8\x48\x01\xDB" def test_mov(): mc = AsmTest() - mc.MOV(IntVar("r15", "Register64"), IntVar("rsp", "Register64")) + mc.MOV(IntVar(Register64("r15")), IntVar(Register64("rsp"))) assert mc.get_as_string() == "\x49\x89\xE7" \ No newline at end of file From iko at codespeak.net Wed Oct 8 14:34:28 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Wed, 8 Oct 2008 14:34:28 +0200 (CEST) Subject: [pypy-svn] r58815 - in pypy/branch/2.5-merge/pypy/lib: . app_test Message-ID: <20081008123428.63A56169E54@codespeak.net> Author: iko Date: Wed Oct 8 14:34:27 2008 New Revision: 58815 Added: pypy/branch/2.5-merge/pypy/lib/app_test/test_collections.py (contents, props changed) Modified: pypy/branch/2.5-merge/pypy/lib/collections.py Log: (iko, cfbolz) fix deque remove failures Added: pypy/branch/2.5-merge/pypy/lib/app_test/test_collections.py ============================================================================== --- (empty file) +++ pypy/branch/2.5-merge/pypy/lib/app_test/test_collections.py Wed Oct 8 14:34:27 2008 @@ -0,0 +1,16 @@ +import py +import collections + +def test_deque_remove_empty(): + d = collections.deque([]) + py.test.raises(ValueError, d.remove, 1) + +def test_deque_remove_mutating(): + class MutatingCmp(object): + def __eq__(self, other): + d.clear() + return True + + d = collections.deque([MutatingCmp()]) + py.test.raises(IndexError, d.remove, 1) + Modified: pypy/branch/2.5-merge/pypy/lib/collections.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/collections.py (original) +++ pypy/branch/2.5-merge/pypy/lib/collections.py Wed Oct 8 14:34:27 2008 @@ -112,7 +112,17 @@ return x def remove(self, value): - del self[operator.indexOf(self, value)] + # Need to be defensive for mutating comparisons + i = 0 + while i < len(self): + if self[i] == value: + if i < len(self): + del self[i] + return + else: + raise IndexError("deque mutated during remove()") + i += 1 + raise ValueError("deque.remove(x): x not in deque") def rotate(self, n=1): length = len(self) From iko at codespeak.net Wed Oct 8 15:02:24 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Wed, 8 Oct 2008 15:02:24 +0200 (CEST) Subject: [pypy-svn] r58817 - in pypy/branch/2.5-merge/pypy/lib: . app_test test2 Message-ID: <20081008130224.1626F169F54@codespeak.net> Author: iko Date: Wed Oct 8 15:02:23 2008 New Revision: 58817 Added: pypy/branch/2.5-merge/pypy/lib/test2/test_collections.py (contents, props changed) - copied, changed from r58815, pypy/branch/2.5-merge/pypy/lib/app_test/test_collections.py Removed: pypy/branch/2.5-merge/pypy/lib/app_test/test_collections.py Modified: pypy/branch/2.5-merge/pypy/lib/collections.py Log: (iko, cfbolz) allow deque subclasses to have extra args in __init__ Modified: pypy/branch/2.5-merge/pypy/lib/collections.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/collections.py (original) +++ pypy/branch/2.5-merge/pypy/lib/collections.py Wed Oct 8 15:02:23 2008 @@ -20,8 +20,8 @@ class deque(object): - def __new__(cls, iterable=()): - self = super(deque, cls).__new__(cls) + def __new__(cls, iterable=(), *args, **kw): + self = super(deque, cls).__new__(cls, *args, **kw) self.clear() return self Copied: pypy/branch/2.5-merge/pypy/lib/test2/test_collections.py (from r58815, pypy/branch/2.5-merge/pypy/lib/app_test/test_collections.py) ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/app_test/test_collections.py (original) +++ pypy/branch/2.5-merge/pypy/lib/test2/test_collections.py Wed Oct 8 15:02:23 2008 @@ -1,5 +1,5 @@ +from pypy.lib import collections import py -import collections def test_deque_remove_empty(): d = collections.deque([]) @@ -14,3 +14,10 @@ d = collections.deque([MutatingCmp()]) py.test.raises(IndexError, d.remove, 1) +class SubclassWithKwargs(collections.deque): + def __init__(self, newarg=1): + collections.deque.__init__(self) + +def test_subclass_with_kwargs(): + # SF bug #1486663 -- this used to erroneously raise a TypeError + SubclassWithKwargs(newarg=1) From cfbolz at codespeak.net Wed Oct 8 15:14:32 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 8 Oct 2008 15:14:32 +0200 (CEST) Subject: [pypy-svn] r58818 - pypy/branch/2.5-merge/pypy/lib Message-ID: <20081008131432.5A59C169F54@codespeak.net> Author: cfbolz Date: Wed Oct 8 15:14:30 2008 New Revision: 58818 Modified: pypy/branch/2.5-merge/pypy/lib/_exceptions.py Log: (iko, cfbolz): fix error message Modified: pypy/branch/2.5-merge/pypy/lib/_exceptions.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/_exceptions.py (original) +++ pypy/branch/2.5-merge/pypy/lib/_exceptions.py Wed Oct 8 15:14:30 2008 @@ -264,11 +264,11 @@ if args[1][1] is None or type(args[1][1]) == int: self.lineno = args[1][1] else: - raise TypeError('argument 2 must be str, not %s'%type(args[1][1])) + raise TypeError('argument 2 must be int, not %s'%type(args[1][1])) if args[1][2] is None or type(args[1][2]) == int: self.offset = args[1][2] else: - raise TypeError('argument 3 must be str, not %s'%type(args[1][2])) + raise TypeError('argument 3 must be int, not %s'%type(args[1][2])) if args[1][3] is None or type(args[1][3]) == str: self.text = args[1][3] else: From iko at codespeak.net Wed Oct 8 15:17:07 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Wed, 8 Oct 2008 15:17:07 +0200 (CEST) Subject: [pypy-svn] r58819 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081008131707.68EBB169F65@codespeak.net> Author: iko Date: Wed Oct 8 15:17:06 2008 New Revision: 58819 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_exceptions.py Log: (iko, cfbolz) SynatxError arg checking is more stringent in PyPy Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_exceptions.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_exceptions.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_exceptions.py Wed Oct 8 15:17:06 2008 @@ -6,7 +6,7 @@ import warnings import pickle, cPickle -from test.test_support import TESTFN, unlink, run_unittest +from test.test_support import TESTFN, unlink, run_unittest, check_impl_details # XXX This is not really enough, each *operation* should be tested! @@ -241,13 +241,6 @@ 'offsetStr', 'textStr')), 'print_file_and_line' : None, 'msg' : 'msgStr', 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}), - (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', - 'textStr', 'print_file_and_lineStr'), - {'message' : '', 'text' : None, - 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', - 'textStr', 'print_file_and_lineStr'), - 'print_file_and_line' : None, 'msg' : 'msgStr', - 'filename' : None, 'lineno' : None, 'offset' : None}), (UnicodeError, (), {'message' : '', 'args' : (),}), (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'), {'message' : '', 'args' : ('ascii', u'a', 0, 1, @@ -264,6 +257,17 @@ 'object' : u'\u3042', 'reason' : 'ouch', 'start' : 0, 'end' : 1}), ] + if check_impl_details: + exceptionList.append( + (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', + 'textStr', 'print_file_and_lineStr'), + {'message' : '', 'text' : None, + 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', + 'textStr', 'print_file_and_lineStr'), + 'print_file_and_line' : None, 'msg' : 'msgStr', + 'filename' : None, 'lineno' : None, 'offset' : None}) + ) + try: exceptionList.append( (WindowsError, (1, 'strErrorStr', 'filenameStr'), From antocuni at codespeak.net Wed Oct 8 15:26:36 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 8 Oct 2008 15:26:36 +0200 (CEST) Subject: [pypy-svn] r58820 - pypy/dist/pypy/tool Message-ID: <20081008132636.D09AC169EC3@codespeak.net> Author: antocuni Date: Wed Oct 8 15:26:35 2008 New Revision: 58820 Added: pypy/dist/pypy/tool/ansicolor.py (contents, props changed) Log: yet another module useful to print colored output Added: pypy/dist/pypy/tool/ansicolor.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/ansicolor.py Wed Oct 8 15:26:35 2008 @@ -0,0 +1,28 @@ +class colors: + black = '30' + darkred = '31' + darkgreen = '32' + brown = '33' + darkblue = '34' + purple = '35' + teal = '36' + lightgray = '37' + darkgray = '30;01' + red = '31;01' + green = '32;01' + yellow = '33;01' + blue = '34;01' + fuchsia = '35;01' + turquoise = '36;01' + white = '37;01' + +def setcolor(s, color): + return '\x1b[%sm%s\x1b[00m' % (color, s) + +for name in colors.__dict__: + if name.startswith('_'): + continue + exec """ +def %s(s): + return setcolor(s, colors.%s) +""" % (name, name) From cfbolz at codespeak.net Wed Oct 8 15:26:41 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 8 Oct 2008 15:26:41 +0200 (CEST) Subject: [pypy-svn] r58821 - pypy/branch/2.5-merge/pypy/interpreter/test Message-ID: <20081008132641.BFD70169EE1@codespeak.net> Author: cfbolz Date: Wed Oct 8 15:26:40 2008 New Revision: 58821 Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_raise.py Log: (iko, cfbolz): We couldn't figure out at all where these test fragments orginally came from. Killing them. Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_raise.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_raise.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_raise.py Wed Oct 8 15:26:40 2008 @@ -237,17 +237,3 @@ except A, a: assert a.__class__ is Sub assert a.val == 42 - -<<<<<<< .working -======= - def test_it(self): - class C: - pass - # this used to explode in the exception normalization step: ->>>>>>> .merge-right.r58379 - try: - {}[5] - except A, a: - assert 0 - except KeyError: - pass From antocuni at codespeak.net Wed Oct 8 15:28:36 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 8 Oct 2008 15:28:36 +0200 (CEST) Subject: [pypy-svn] r58822 - in pypy/dist/pypy: bin config translator translator/tool Message-ID: <20081008132836.C6372169EC8@codespeak.net> Author: antocuni Date: Wed Oct 8 15:28:35 2008 New Revision: 58822 Added: pypy/dist/pypy/bin/reportstaticdata.py (contents, props changed) Modified: pypy/dist/pypy/config/translationoption.py pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/tool/staticsizereport.py Log: (antocuni, xoraxax) - add an option to translate.py to save the info about static data - add a script to produce report using that data Added: pypy/dist/pypy/bin/reportstaticdata.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/bin/reportstaticdata.py Wed Oct 8 15:28:35 2008 @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +""" +Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME +Print a report for the static data informations contained in FILENAME + +The static data informations are saved in the file staticdata.info when +passing --dump_static_data_info to translate.py. + +Options: + + -m1 Print a report for each module, counting constants that are + reacheable from more than one module multiple times (default) + + -m2 Print a report for each module, counting constants that are + reacheable from more than one module only in the first module + seen + + -t Print a global report for all the constants + + -h Print sizes in human readable formats (e.g., 1K 234M) + + -s Print only the total size for each module + + -u Print the list of graphs which belongs to unknown modules + + --help Show this help message +""" + +import autopath +from pypy.translator.tool.staticsizereport import print_report + +def parse_options(argv): + kwds = {} + for arg in argv: + if arg.startswith('-'): + if arg == '-m1': + assert 'kind' not in kwds + kwds['kind'] = 'by_module_with_duplicates' + elif arg == '-m2': + assert 'kind' not in kwds + kwds['kind'] = 'by_module_without_duplicates' + elif arg == '-t': + assert 'kind' not in kwds + kwds['kind'] = 'by_type' + elif arg == '-h': + kwds['human_readable'] = True + elif arg == '-s': + kwds['summary'] = True + elif arg == '-u': + kwds['show_unknown_graphs'] = True + elif arg == '--help': + raise AssertionError + else: + assert 'filename' not in kwds + kwds['filename'] = arg + + assert 'filename' in kwds + return kwds + + +def main(): + import sys + try: + kwds = parse_options(sys.argv[1:]) + except AssertionError: + print >> sys.stderr, __doc__ + sys.exit(1) + print_report(**kwds) + +if __name__ == '__main__': + main() Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Wed Oct 8 15:28:35 2008 @@ -122,6 +122,10 @@ default=None), StrOption("output", "Output file name", cmdline="--output"), + BoolOption("dump_static_data_info", "Dump static data info", + cmdline="--dump_static_data_info", + default=False, requires=[("translation.backend", "c")]), + # portability options BoolOption("vanilla", "Try to be as portable as possible, which is not much", Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Wed Oct 8 15:28:35 2008 @@ -491,6 +491,11 @@ database = self.database c_source_filename = cbuilder.generate_source(database) self.log.info("written: %s" % (c_source_filename,)) + if self.config.translation.dump_static_data_info: + from pypy.translator.tool.staticsizereport import dump_static_data_info + targetdir = cbuilder.targetdir + dump_static_data_info(self.log, database, targetdir) + # task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source") Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Wed Oct 8 15:28:35 2008 @@ -1,10 +1,40 @@ from __future__ import division +import cPickle as pickle +from pypy.tool.ansicolor import red, yellow, green from pypy.rpython.lltypesystem.lltype import typeOf, _ptr, Ptr, ContainerType from pypy.rpython.lltypesystem import llmemory from pypy.rpython.memory.lltypelayout import convert_offset_to_int +class Info: + pass +class ModuleReport: + def __init__(self, modulename, totalsize, typereports): + self.modulename = modulename + self.totalsize = totalsize + self.typereports = typereports + + def __repr__(self): + return 'ModuleReport(%s, %d, ...)' % (self.modulename, self.totalsize) + + def __cmp__(self, other): + return cmp((self.totalsize, self.modulename), (other.totalsize, other.modulename)) + +class TypeReport: + def __init__(self, typename, size, numobjects): + self.typename = typename + self.size = size + self.numobjects = numobjects + + def __repr__(self): + return 'TypeReport(%s, %d, %d)' % (self.typename, self.size, self.numobjects) + + def __cmp__(self, other): + return cmp((self.size, self.typename), (other.size, other.typename)) + + +## Functions used by translate.py def guess_module(graph): func = getattr(graph, 'func', None) name = None @@ -60,7 +90,7 @@ def by_lltype(obj): - return typeOf(obj) + return repr(typeOf(obj)) def group_static_size(database, nodes, grouper=by_lltype, recursive=None): totalsize = {} @@ -78,22 +108,11 @@ l.sort() l.reverse() sizesum = 0 - report = [] + typereports = [] for size, key in l: sizesum += size - report.append((key, size, numobjects[key], size / numobjects[key])) - return sizesum, report - -def format_report_line(line): - return str(line[0])[:50] + " " + " ".join([str(x) for x in line[1:]]) - - -def print_report_static_size(database, grouper=by_lltype): - " Reports all objects with a specified grouper. " - _, report = make_report_static_size(database.globalcontainers(), grouper) - for line in report: - print format_report_line(line) - + typereports.append(TypeReport(key, size, numobjects[key])) + return sizesum, typereports def get_unknown_graphs(database): funcnodes = [node for node in database.globalcontainers() if node.nodekind == "func"] @@ -104,7 +123,14 @@ if not guess_module(graph): yield graph -def print_aggregated_values_by_module_and_type(database, count_modules_separately=False, verbose=False): +def get_unknown_graphs_names(database): + return [getattr(graph, 'name', '???') for graph in get_unknown_graphs(database)] + +def aggregate_values_by_type(database): + size, typereports = make_report_static_size(database, database.globalcontainers(), by_lltype) + return [ModuleReport('', size, typereports)] + +def aggregate_values_by_module_and_type(database, count_modules_separately=False): " Reports all objects by module and by lltype. " modules = {} reports = [] @@ -133,18 +159,69 @@ seen = set() if not nodes: continue - size, report = make_report_static_size(database, nodes, by_lltype, seen) - reports.append((size, modulename, report)) + size, typereports = make_report_static_size(database, nodes, by_lltype, seen) + reports.append(ModuleReport(modulename, size, typereports)) reports.sort() reports.reverse() - for size, modulename, report in reports: - if not size: + return reports + +def dump_static_data_info(log, database, targetdir): + info = Info() + info.by_module_with_duplicates = aggregate_values_by_module_and_type(database, False) + info.by_module_without_duplicates = aggregate_values_by_module_and_type(database, True) + info.by_type = aggregate_values_by_type(database) + info.unknown_graphs = get_unknown_graphs_names(database) + infofile = targetdir.join('staticdata.info') + f = infofile.open('w') + pickle.dump(info, f) + f.close() + log.info('static data informations dumped to %s' % infofile) + + +## Functions used by the reportstaticdata.py script +def format_typereport(rep, human_readable=True): + size = format_size(rep.size, human_readable) + return format_line(rep.typename[:50], size, rep.numobjects) + +def format_line(a, b, c): + return ' %50s %10s %6s' % (a, b, c) + +def format_size(size, human_readable=False): + KB = 1024.0 + MB = KB*KB + if human_readable: + if size >= MB: + return '%.2fM' % (size/MB) + if size >= KB: + return '%.2fK' % (size/KB) + return '%d' % size + return size + +def print_report(filename, + kind='by_module_with_duplicates', + summary=False, + show_unknown_graphs=False, + human_readable=True): + f = open(filename) + info = pickle.load(f) + f.close() + reports = getattr(info, kind) + + for report in reports: + if report.totalsize == 0: continue - if verbose: - print "########### %i %s ####################################" % (size, modulename) - for line in report: - print " " * 4 + format_report_line(line) - print + size = format_size(report.totalsize, human_readable) + if summary: + print "%d\t%s" % (size, report.modulename) else: - print "%i\%s" % (size, modulename) + print '%s: %s' % (red(report.modulename), yellow(size)) + print green(format_line('Typename', 'Size', 'Num')) + for typereport in report.typereports: + print format_typereport(typereport, human_readable) + print + if show_unknown_graphs: + print + print green('Unknown graphs:') + for graphname in info.unknown_graphs: + print graphname From pedronis at codespeak.net Wed Oct 8 15:30:22 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 15:30:22 +0200 (CEST) Subject: [pypy-svn] r58823 - pypy/build/bot2/pypybuildbot Message-ID: <20081008133022.24184169F15@codespeak.net> Author: pedronis Date: Wed Oct 8 15:30:21 2008 New Revision: 58823 Modified: pypy/build/bot2/pypybuildbot/summary.py Log: better display of translation failures, the build link will point to the failed step(translation) log Modified: pypy/build/bot2/pypybuildbot/summary.py ============================================================================== --- pypy/build/bot2/pypybuildbot/summary.py (original) +++ pypy/build/bot2/pypybuildbot/summary.py Wed Oct 8 15:30:21 2008 @@ -4,6 +4,7 @@ html = py.xml.html from buildbot.status.web.base import HtmlResource +from buildbot.status.builder import FAILURE class RevisionOutcomeSet(object): @@ -80,19 +81,29 @@ rev = int(build.getProperty("got_revision")) pytest_log = None - stdio_url = "no_log" + stdio_log = None + failure = None for step in build.getSteps(): logs = dict((log.getName(), log) for log in step.getLogs()) if 'pytestLog' in logs: pytest_log = logs['pytestLog'] - stdio_url = status.getURLForThing(logs['stdio']) - # builbot is broken in this :( - stdio_url = stdio_url[:-1]+"stdio" + stdio_log = logs['stdio'] break + elif stdio_log is None and step.getResults()[0] == FAILURE: + failure = ' '.join(step.getText()) + stdio_log = logs.get('stdio') + if stdio_log is None: + stdio_url = "no_log" + else: + stdio_url = status.getURLForThing(stdio_log) + # builbot is broken in this :( + stdio_url = stdio_url[:-1]+"stdio" + outcome_set = RevisionOutcomeSet(rev, key, stdio_url) if pytest_log is None or not pytest_log.hasContents(): - outcome_set.populate_one('', '!', "no log from the test run") + name = failure or '' + outcome_set.populate_one(name, '!', "no log from the test run") else: outcome_set.populate(pytest_log) return outcome_set From pedronis at codespeak.net Wed Oct 8 15:34:59 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 15:34:59 +0200 (CEST) Subject: [pypy-svn] r58824 - pypy/build/bot2 Message-ID: <20081008133459.6E484169EF2@codespeak.net> Author: pedronis Date: Wed Oct 8 15:34:58 2008 New Revision: 58824 Modified: pypy/build/bot2/TODO Log: reporting translation failures is done now Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Wed Oct 8 15:34:58 2008 @@ -6,8 +6,6 @@ - some kind of progress information for a run -- report translation failures in the summary somehow - - support for better information in case of runner-level killed hanging tests - build/support for running cpython on tests, adaptations to produce structured logs and be compatible From arigo at codespeak.net Wed Oct 8 15:35:25 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 15:35:25 +0200 (CEST) Subject: [pypy-svn] r58825 - pypy/branch/2.5-merge/pypy/interpreter/test Message-ID: <20081008133525.ED070169EF2@codespeak.net> Author: arigo Date: Wed Oct 8 15:35:25 2008 New Revision: 58825 Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_raise.py Log: * Restored the bit that iko and cfbolz lost in r58821. * Fix test for new-style class support. Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_raise.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_raise.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_raise.py Wed Oct 8 15:35:25 2008 @@ -192,7 +192,8 @@ raises(TypeError, f) def test_it(self): - C = _classobj('C', (), {}) + class C: + pass # this used to explode in the exception normalization step: try: {}[C] @@ -201,7 +202,6 @@ def test_oldstyle_userclass(self): class A: - __metaclass__ = _classobj def __init__(self, val=None): self.val = val class Sub(A): @@ -237,3 +237,10 @@ except A, a: assert a.__class__ is Sub assert a.val == 42 + + try: + {}[5] + except A, a: + assert 0 + except KeyError: + pass From cfbolz at codespeak.net Wed Oct 8 15:47:40 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 8 Oct 2008 15:47:40 +0200 (CEST) Subject: [pypy-svn] r58826 - in pypy/branch/2.5-merge/pypy/module/_file: . test Message-ID: <20081008134740.EFF3F169F18@codespeak.net> Author: cfbolz Date: Wed Oct 8 15:47:40 2008 New Revision: 58826 Modified: pypy/branch/2.5-merge/pypy/module/_file/interp_file.py pypy/branch/2.5-merge/pypy/module/_file/test/test_file.py Log: (iko, cfbolz): raise ValueError instead of IOError when the mode is nonsensical Modified: pypy/branch/2.5-merge/pypy/module/_file/interp_file.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_file/interp_file.py (original) +++ pypy/branch/2.5-merge/pypy/module/_file/interp_file.py Wed Oct 8 15:47:40 2008 @@ -50,7 +50,7 @@ def check_mode_ok(self, mode): if not mode or mode[0] not in ['r', 'w', 'a', 'U']: space = self.space - raise OperationError(space.w_IOError, + raise OperationError(space.w_ValueError, space.wrap('invalid mode : "%s"' % mode)) def getstream(self): Modified: pypy/branch/2.5-merge/pypy/module/_file/test/test_file.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_file/test/test_file.py (original) +++ pypy/branch/2.5-merge/pypy/module/_file/test/test_file.py Wed Oct 8 15:47:40 2008 @@ -86,7 +86,7 @@ f.close() def test_badmode(self): - raises(IOError, self.file, "foo", "bar") + raises(ValueError, self.file, "foo", "bar") def test_wraposerror(self): raises(IOError, self.file, "hopefully/not/existant.bar") From fijal at codespeak.net Wed Oct 8 15:47:49 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 8 Oct 2008 15:47:49 +0200 (CEST) Subject: [pypy-svn] r58827 - pypy/dist/pypy/rpython/memory/gc Message-ID: <20081008134749.3460B169F54@codespeak.net> Author: fijal Date: Wed Oct 8 15:47:48 2008 New Revision: 58827 Modified: pypy/dist/pypy/rpython/memory/gc/markcompact.py Log: * change assert to ll_asert * fix performance hack, that doesn't work Modified: pypy/dist/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/dist/pypy/rpython/memory/gc/markcompact.py Wed Oct 8 15:47:48 2008 @@ -85,12 +85,14 @@ def init_gc_object_immortal(self, addr, typeid, flags=0): hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) hdr.tid = typeid | flags | GCFLAG_EXTERNAL - hdr.forward_ptr = addr # so that get_forwarding_address(obj) returns - # obj itself if obj is a prebuilt object + hdr.forward_ptr = NULL + # XXX we can store forward_ptr to itself, if we fix C backend + # so that get_forwarding_address(obj) returns + # obj itself if obj is a prebuilt object def malloc_fixedsize_clear(self, typeid, size, can_collect, has_finalizer=False, contains_weakptr=False): - assert can_collect + ll_assert(can_collect, "can collect is False") size_gc_header = self.gcheaderbuilder.size_gc_header totalsize = size_gc_header + size result = self.free @@ -110,7 +112,7 @@ def malloc_varsize_clear(self, typeid, length, size, itemsize, offset_to_length, can_collect, has_finalizer=False): - assert can_collect + ll_assert(can_collect, "can collect is False") size_gc_header = self.gcheaderbuilder.size_gc_header nonvarsize = size_gc_header + size try: @@ -308,6 +310,8 @@ return self.header(obj).tid & GCFLAG_EXTERNAL def get_forwarding_address(self, obj): + if self._is_external(obj): + return obj return self.header(obj).forward_ptr + self.size_gc_header() def set_forwarding_address(self, obj, newaddr): From fijal at codespeak.net Wed Oct 8 15:50:28 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 8 Oct 2008 15:50:28 +0200 (CEST) Subject: [pypy-svn] r58828 - pypy/dist/pypy/translator/c/src Message-ID: <20081008135028.E5726169F18@codespeak.net> Author: fijal Date: Wed Oct 8 15:50:28 2008 New Revision: 58828 Modified: pypy/dist/pypy/translator/c/src/mem.h Log: Ignore GC_Warning. We don't plan to do anything with them anyway. Modified: pypy/dist/pypy/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/dist/pypy/translator/c/src/mem.h Wed Oct 8 15:50:28 2008 @@ -177,11 +177,17 @@ } boehm_gc_finalizer_lock--; } + +void ignore(char *msg, GC_word arg) +{ +} + void boehm_gc_startup_code(void) { GC_init(); GC_finalizer_notifier = &boehm_gc_finalizer_notifier; GC_finalize_on_demand = 1; + GC_set_warn_proc(ignore); } #endif /* PYPY_NOT_MAIN_FILE */ From jlg at codespeak.net Wed Oct 8 15:58:23 2008 From: jlg at codespeak.net (jlg at codespeak.net) Date: Wed, 8 Oct 2008 15:58:23 +0200 (CEST) Subject: [pypy-svn] r58829 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081008135823.05F82169E9A@codespeak.net> Author: jlg Date: Wed Oct 8 15:58:23 2008 New Revision: 58829 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_file.py Log: removed typo Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_file.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_file.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_file.py Wed Oct 8 15:58:23 2008 @@ -298,7 +298,7 @@ testline = testlines.pop(0) try: line = f.read(len(testline)) - except ValueErrori + except ValueError: self.fail("read() after next() with supposedly empty " "iteration-buffer failed anyway") if line != testline: From xoraxax at codespeak.net Wed Oct 8 16:00:26 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 8 Oct 2008 16:00:26 +0200 (CEST) Subject: [pypy-svn] r58830 - pypy/dist/pypy/translator/c/src Message-ID: <20081008140026.90C49169E99@codespeak.net> Author: xoraxax Date: Wed Oct 8 16:00:26 2008 New Revision: 58830 Modified: pypy/dist/pypy/translator/c/src/mem.h Log: Make the warn proc handler static. Modified: pypy/dist/pypy/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/dist/pypy/translator/c/src/mem.h Wed Oct 8 16:00:26 2008 @@ -178,7 +178,7 @@ boehm_gc_finalizer_lock--; } -void ignore(char *msg, GC_word arg) +static void mem_boehm_ignore(char *msg, GC_word arg) { } @@ -187,7 +187,7 @@ GC_init(); GC_finalizer_notifier = &boehm_gc_finalizer_notifier; GC_finalize_on_demand = 1; - GC_set_warn_proc(ignore); + GC_set_warn_proc(mem_boehm_ignore); } #endif /* PYPY_NOT_MAIN_FILE */ From pedronis at codespeak.net Wed Oct 8 16:32:29 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 16:32:29 +0200 (CEST) Subject: [pypy-svn] r58831 - pypy/build/bot2 Message-ID: <20081008143229.35F32169E77@codespeak.net> Author: pedronis Date: Wed Oct 8 16:32:28 2008 New Revision: 58831 Modified: pypy/build/bot2/TODO Log: running cpython own tests on translated pypy-c now works Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Wed Oct 8 16:32:28 2008 @@ -8,9 +8,6 @@ - support for better information in case of runner-level killed hanging tests -- build/support for running cpython on tests, adaptations to produce structured logs and be compatible - with the py.lib trunk are probably necessary for lib-python/conftest.py TESTING - - pypy-c py.test -A support - look into why the full summary page but not single rev is slowish From pedronis at codespeak.net Wed Oct 8 16:44:19 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 16:44:19 +0200 (CEST) Subject: [pypy-svn] r58832 - pypy/build/bot2 Message-ID: <20081008144419.E96F9169F49@codespeak.net> Author: pedronis Date: Wed Oct 8 16:44:19 2008 New Revision: 58832 Modified: pypy/build/bot2/TODO Log: some more todos Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Wed Oct 8 16:44:19 2008 @@ -14,3 +14,7 @@ - have a way for the involved tool to avoid color escapes even when there's a tty (because of buildbot pty usage) +- move most buildbots to be over python 2.5 (?) + +- wire windows slave + From cfbolz at codespeak.net Wed Oct 8 16:44:33 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 8 Oct 2008 16:44:33 +0200 (CEST) Subject: [pypy-svn] r58833 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081008144433.38710169F49@codespeak.net> Author: cfbolz Date: Wed Oct 8 16:44:32 2008 New Revision: 58833 Added: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_time.py - copied unchanged from r58817, pypy/branch/2.5-merge/lib-python/2.5.2/test/test_time.py Log: (iko, cfbolz): we need to change this, copying it first From xoraxax at codespeak.net Wed Oct 8 16:47:12 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 8 Oct 2008 16:47:12 +0200 (CEST) Subject: [pypy-svn] r58834 - pypy/build/bin Message-ID: <20081008144712.B0AD4168436@codespeak.net> Author: xoraxax Date: Wed Oct 8 16:47:12 2008 New Revision: 58834 Added: pypy/build/bin/nm_symbolgrep.py (contents, props changed) Log: Add a very small cmdline tool to grep the symbol table and aggregate sizes. Added: pypy/build/bin/nm_symbolgrep.py ============================================================================== --- (empty file) +++ pypy/build/bin/nm_symbolgrep.py Wed Oct 8 16:47:12 2008 @@ -0,0 +1,14 @@ +#!/bin/python +import py, sys + +out = py.process.cmdexec("nm -S --size-sort -t d " + sys.argv[1]) +cnt = 0 +sizesum = 0 + +for line in out.splitlines(): + if sys.argv[2] in line: + cnt += 1 + sizesum += int(line.split(" ")[1]) + +print cnt, sizesum + From iko at codespeak.net Wed Oct 8 16:48:58 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Wed, 8 Oct 2008 16:48:58 +0200 (CEST) Subject: [pypy-svn] r58835 - in pypy/branch/2.5-merge: lib-python/modified-2.5.2/test pypy/module/_file pypy/module/_file/test Message-ID: <20081008144858.11678169EAE@codespeak.net> Author: iko Date: Wed Oct 8 16:48:57 2008 New Revision: 58835 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_file.py pypy/branch/2.5-merge/pypy/module/_file/interp_file.py pypy/branch/2.5-merge/pypy/module/_file/test/test_file_extra.py Log: (iko, cfbolz) Fix file tests Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_file.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_file.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_file.py Wed Oct 8 16:48:57 2008 @@ -6,6 +6,7 @@ from weakref import proxy from test.test_support import TESTFN, findfile, run_unittest +from test.test_support import gc_collect, impl_detail from UserList import UserList class AutoFileTests(unittest.TestCase): @@ -26,6 +27,7 @@ self.assertEquals(self.f.name, p.name) self.f.close() self.f = None + gc_collect() self.assertRaises(ReferenceError, getattr, p, 'name') def testAttributes(self): @@ -218,6 +220,7 @@ finally: os.unlink(TESTFN) + @impl_detail def testIteration(self): # Test the complex interaction when mixing file-iteration and the # various read* methods. Ostensibly, the mixture could just be tested Modified: pypy/branch/2.5-merge/pypy/module/_file/interp_file.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_file/interp_file.py (original) +++ pypy/branch/2.5-merge/pypy/module/_file/interp_file.py Wed Oct 8 16:48:57 2008 @@ -8,6 +8,7 @@ from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, make_weakref_descr +from pypy.interpreter.typedef import interp_attrproperty_w from pypy.interpreter.gateway import interp2app @@ -37,9 +38,9 @@ self.clear_all_weakrefs() self.direct_close() - def fdopenstream(self, stream, fd, mode, name): + def fdopenstream(self, stream, fd, mode, w_name): self.fd = fd - self.name = name + self.w_name = w_name self.softspace = 0 # Required according to file object docs self.encoding = None # This is not used internally by file objects self.mode = mode @@ -78,12 +79,13 @@ # The 'direct_' methods assume that the caller already acquired the # file lock. They don't convert StreamErrors to OperationErrors, too. - def direct___init__(self, name, mode='r', buffering=-1): + def direct___init__(self, w_name, mode='r', buffering=-1): + name = self.space.str_w(w_name) self.direct_close() self.check_mode_ok(mode) stream = streamio.open_file_as_stream(name, mode, buffering) fd = stream.try_to_find_file_descriptor() - self.fdopenstream(stream, fd, mode, name) + self.fdopenstream(stream, fd, mode, w_name) def direct___enter__(self): if self.stream is None: @@ -101,7 +103,7 @@ self.direct_close() self.check_mode_ok(mode) stream = streamio.fdopen_as_stream(fd, mode, buffering) - self.fdopenstream(stream, fd, mode, '') + self.fdopenstream(stream, fd, mode, self.space.wrap('')) def direct_close(self): space = self.space @@ -282,7 +284,7 @@ class_scope['_exposed_method_names'].append(name) - _decl(locals(), "__init__", ['self', str, str, int], + _decl(locals(), "__init__", ['self', W_Root, str, int], """Opens a file.""") _decl(locals(), "__enter__", ['self'], """__enter__() -> self.""") @@ -384,7 +386,8 @@ head = "closed" else: head = "open" - info = "%s file '%s', mode '%s'" % (head, self.name, self.mode) + repr_filename = self.space.str_w(self.space.repr(self.w_name)) + info = "%s file %s, mode '%s'" % (head, repr_filename, self.mode) return self.getrepr(self.space, info) file__repr__.unwrap_spec = ['self'] @@ -467,7 +470,7 @@ """, __new__ = interp2app(descr_file__new__), fdopen = interp2app(descr_file_fdopen, as_classmethod=True), - name = interp_attrproperty('name', cls=W_File, doc="file name"), + name = interp_attrproperty_w('w_name', cls=W_File, doc="file name"), mode = interp_attrproperty('mode', cls=W_File, doc = "file mode ('r', 'U', 'w', 'a', " "possibly with 'b' or '+' added)"), Modified: pypy/branch/2.5-merge/pypy/module/_file/test/test_file_extra.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_file/test/test_file_extra.py (original) +++ pypy/branch/2.5-merge/pypy/module/_file/test/test_file_extra.py Wed Oct 8 16:48:57 2008 @@ -566,3 +566,9 @@ def test_docstrings(self): assert file.closed.__doc__ == 'True if the file is closed' + + def test_repr_unicode_filename(self): + f = open(unicode(self.temptestfile), 'w') + assert repr(f).startswith(" Author: pedronis Date: Wed Oct 8 17:06:19 2008 New Revision: 58836 Modified: pypy/branch/2.5-merge/lib-python/conftest.py Log: support the keyword skip on RegrTests to skip all tests at the conftest level, skip=True => "obsolete or unsupported platform" as skip message other true skip value => used directly as the skip message Modified: pypy/branch/2.5-merge/lib-python/conftest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/conftest.py (original) +++ pypy/branch/2.5-merge/lib-python/conftest.py Wed Oct 8 17:06:19 2008 @@ -58,13 +58,15 @@ def __init__(self, basename, enabled=False, dumbtest=False, core=False, compiler=None, - usemodules = ''): + usemodules = '', + skip=None): self.basename = basename self.enabled = enabled self.dumbtest = dumbtest self._usemodules = usemodules.split() self._compiler = compiler self.core = core + self.skip = skip assert self.getfspath().check(), "%r not found!" % (basename,) def usemodules(self): @@ -122,7 +124,7 @@ RegrTest('test___future__.py', enabled=True, dumbtest=1, core=True), RegrTest('test__locale.py', enabled=True), RegrTest('test_aepack.py', enabled=False), - RegrTest('test_al.py', enabled=False, dumbtest=1), + RegrTest('test_al.py', enabled=False, dumbtest=1, skip=True), RegrTest('test_anydbm.py', enabled=True), RegrTest('test_applesingle.py', enabled=False), RegrTest('test_array.py', enabled=True, core=True, usemodules='struct'), @@ -658,6 +660,12 @@ i am afraid. """ regrtest = self.parent.regrtest + if regrtest.skip: + if regrtest.skip is True: + msg = "obsolete or unsupported platform" + else: + msg = regrtest.skip + py.test.skip(msg) exit_status, test_stdout, test_stderr = self.getresult(regrtest) if exit_status: raise self.ExternalFailure(test_stdout, test_stderr) From xoraxax at codespeak.net Wed Oct 8 17:14:25 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 8 Oct 2008 17:14:25 +0200 (CEST) Subject: [pypy-svn] r58837 - in pypy/dist/pypy: config interpreter rlib rlib/test translator/goal Message-ID: <20081008151425.9B063169FA3@codespeak.net> Author: xoraxax Date: Wed Oct 8 17:14:23 2008 New Revision: 58837 Added: pypy/dist/pypy/rlib/test/test_timer.py pypy/dist/pypy/rlib/timer.py Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: Added trivial timing system that can be used on systems without a profiler. It is disabled by default. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Wed Oct 8 17:14:23 2008 @@ -168,6 +168,10 @@ "make sure that all calls go through space.call_args", default=False), + BoolOption("timing", + "timing of various parts of the interpreter (simple profiling)", + default=False), + OptionDescription("std", "Standard Object Space Options", [ BoolOption("withtproxy", "support transparent proxies", default=True), Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Oct 8 17:14:23 2008 @@ -9,6 +9,7 @@ from pypy.tool.uid import HUGEVAL_BYTES from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized +from pypy.rlib.timer import DummyTimer, Timer import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -252,6 +253,11 @@ # if self.config.objspace.logbytecodes: # self.bytecodecounts = {} + if self.config.objspace.timing: + self.timer = Timer() + else: + self.timer = DummyTimer() + self.initialize() def startup(self): @@ -264,7 +270,10 @@ modname = self.str_w(w_modname) mod = self.interpclass_w(self.getbuiltinmodule(modname)) if isinstance(mod, Module): + import time + self.timer.start("startup " + modname) mod.startup(self) + self.timer.stop("startup " + modname) def finish(self): w_exitfunc = self.sys.getdictvalue_w(self, 'exitfunc') Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Wed Oct 8 17:14:23 2008 @@ -242,6 +242,7 @@ ## flags |= stdlib___future__.generators.compiler_flag # always on (2.2 compat) space = self.space + space.timer.start("PythonAST compile") try: builder = AstBuilder(self.parser, self.grammar_version, space=space) for rulename, buildfunc in self.additional_rules.iteritems(): @@ -283,6 +284,7 @@ except (ValueError, TypeError), e: raise OperationError(space.w_SystemError, space.wrap(str(e))) assert isinstance(c, PyCode) + space.timer.stop("PythonAST compile") return c # interface for pypy.module.recparser Added: pypy/dist/pypy/rlib/test/test_timer.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/test/test_timer.py Wed Oct 8 17:14:23 2008 @@ -0,0 +1,20 @@ +from pypy.rlib.timer import Timer +from pypy.translator.c.test.test_genc import compile +from pypy.annotation.policy import AnnotatorPolicy + +def timer_user(): + t = Timer() + t.start("testa") + t.stop("testa") + t.start("testb") + t.start("testb") + t.stop("testb") + t.stop("testb") + t.dump() + +def test_compile_timer(): + policy = AnnotatorPolicy() + policy.allow_someobjects = False + f_compiled = compile(timer_user, [], annotatorpolicy=policy) + f_compiled(expected_extra_mallocs=0) + Added: pypy/dist/pypy/rlib/timer.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/timer.py Wed Oct 8 17:14:23 2008 @@ -0,0 +1,61 @@ +import time +import os + + +def _create_name(name, generation): + if generation == 0: + return name + else: + return "%s[%s]" % (name, str(generation)) + + +class Timer: + def __init__(self): + self.timings = {} + self.levels = {} + self.timingorder = [] + + def start(self, timer): + level = self.levels.setdefault(timer, -1) + new_level = level + 1 + name = _create_name(timer, new_level) + if name not in self.timings: + self.timingorder.append(name) + self.timings[name] = time.time() - self.timings.get(name, 0) + self.levels[timer] = new_level + + def stop(self, timer): + level = self.levels.setdefault(timer, -1) + if level == -1: + raise ValueError("Invalid timer name") + if level >= 0: # timer is active + name = _create_name(timer, level) + self.timings[name] = time.time() - self.timings[name] + self.levels[timer] = level - 1 + + def value(self, timer): + level = self.levels.get(timer, -1) + if level == -1: + result = "%fs" % self.timings[timer] + else: + result = "%fs (still running)" % (time.time() - self.timings[timer]) + return result + + def dump(self): + outlist = [] + for timer in self.timingorder: + value = self.value(timer) + outlist.append("%s = %s" % (timer, value)) + os.write(2, "\n".join(outlist)) + + +class DummyTimer: + def start(self, timer): + pass + def stop(self, timer): + pass + def value(self, timer): + return "Timing disabled" + def dump(self): + pass + Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Wed Oct 8 17:14:23 2008 @@ -31,6 +31,7 @@ w_os = setup_nanos(space) def entry_point(argv): + space.timer.start("Entrypoint") #debug("entry point starting") #for arg in argv: # debug(" argv -> " + arg) @@ -45,10 +46,14 @@ argv = argv[:1] + argv[3:] try: try: + space.timer.start("space.startup") space.call_function(w_run_toplevel, w_call_startup_gateway) + space.timer.stop("space.startup") w_executable = space.wrap(argv[0]) w_argv = space.newlist([space.wrap(s) for s in argv[1:]]) + space.timer.start("w_entry_point") w_exitcode = space.call_function(w_entry_point, w_executable, w_argv, w_os) + space.timer.stop("w_entry_point") exitcode = space.int_w(w_exitcode) # try to pull it all in ## from pypy.interpreter import main, interactive, error @@ -61,12 +66,16 @@ return 1 finally: try: + space.timer.start("space.finish") space.call_function(w_run_toplevel, w_call_finish_gateway) + space.timer.stop("space.finish") except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) debug(" operror-value: " + space.str_w(space.str(e.w_value))) return 1 + space.timer.stop("Entrypoint") + space.timer.dump() return exitcode return entry_point From cfbolz at codespeak.net Wed Oct 8 17:54:54 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 8 Oct 2008 17:54:54 +0200 (CEST) Subject: [pypy-svn] r58838 - pypy/branch/2.5-merge/lib-python Message-ID: <20081008155454.3D058169E44@codespeak.net> Author: cfbolz Date: Wed Oct 8 17:54:52 2008 New Revision: 58838 Modified: pypy/branch/2.5-merge/lib-python/conftest.py Log: (cfbolz, iko, samuele around): review all tests and skip some of them Modified: pypy/branch/2.5-merge/lib-python/conftest.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/conftest.py (original) +++ pypy/branch/2.5-merge/lib-python/conftest.py Wed Oct 8 17:54:52 2008 @@ -55,14 +55,11 @@ class RegrTest: """ Regression Test Declaration.""" - def __init__(self, basename, enabled=False, dumbtest=False, - core=False, + def __init__(self, basename, core=False, compiler=None, usemodules = '', skip=None): self.basename = basename - self.enabled = enabled - self.dumbtest = dumbtest self._usemodules = usemodules.split() self._compiler = compiler self.core = core @@ -119,424 +116,369 @@ ''' % locals()) testmap = [ - RegrTest('test___all__.py', enabled=True, core=True), - # fixable - RegrTest('test___future__.py', enabled=True, dumbtest=1, core=True), - RegrTest('test__locale.py', enabled=True), - RegrTest('test_aepack.py', enabled=False), - RegrTest('test_al.py', enabled=False, dumbtest=1, skip=True), - RegrTest('test_anydbm.py', enabled=True), - RegrTest('test_applesingle.py', enabled=False), - RegrTest('test_array.py', enabled=True, core=True, usemodules='struct'), - RegrTest('test_asynchat.py', enabled=False, usemodules='thread'), - RegrTest('test_atexit.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_audioop.py', enabled=False, dumbtest=1), - RegrTest('test_augassign.py', enabled=True, core=True), - RegrTest('test_base64.py', enabled=True), - RegrTest('test_bastion.py', enabled=True, dumbtest=1), - RegrTest('test_binascii.py', enabled=False), - #rev 10840: 2 of 8 tests fail - - RegrTest('test_binhex.py', enabled=False), - #rev 10840: 1 of 1 test fails - - RegrTest('test_binop.py', enabled=True, core=True), - RegrTest('test_bisect.py', enabled=True, core=True), - RegrTest('test_bool.py', enabled=True, core=True), - RegrTest('test_bsddb.py', enabled=False), - RegrTest('test_bsddb185.py', enabled=False), - RegrTest('test_bsddb3.py', enabled=False), - RegrTest('test_bufio.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_builtin.py', enabled=True, core=True), - RegrTest('test_bz2.py', usemodules='bz2', enabled=True), - RegrTest('test_calendar.py', enabled=True), - RegrTest('test_call.py', enabled=True, core=True), - RegrTest('test_capi.py', enabled=False, dumbtest=1), - RegrTest('test_cd.py', enabled=False, dumbtest=1), - RegrTest('test_cfgparser.py', enabled=False), - #rev 10840: Uncaught interp-level exception: - #File "pypy/objspace/std/fake.py", line 133, in setfastscope - #raise UnwrapError('calling %s: %s' % (self.code.cpy_callable, e)) - #pypy.objspace.std.model.UnwrapError: calling : cannot unwrap > - - RegrTest('test_cgi.py', enabled=True), - RegrTest('test_charmapcodec.py', enabled=True, core=True), - RegrTest('test_cl.py', enabled=False, dumbtest=1), - RegrTest('test_class.py', enabled=True, core=True), - RegrTest('test_cmath.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_codeccallbacks.py', enabled=True, core=True), - RegrTest('test_codecencodings_cn.py', enabled=False), - RegrTest('test_codecencodings_hk.py', enabled=False), - RegrTest('test_codecencodings_jp.py', enabled=False), - RegrTest('test_codecencodings_kr.py', enabled=False), - RegrTest('test_codecencodings_tw.py', enabled=False), - - RegrTest('test_codecmaps_cn.py', enabled=False), - RegrTest('test_codecmaps_hk.py', enabled=False), - RegrTest('test_codecmaps_jp.py', enabled=False), - RegrTest('test_codecmaps_kr.py', enabled=False), - RegrTest('test_codecmaps_tw.py', enabled=False), - RegrTest('test_codecs.py', enabled=True, core=True), - RegrTest('test_codeop.py', enabled=True, core=True), - RegrTest('test_coercion.py', enabled=True, core=True), + RegrTest('test___all__.py', core=True), + RegrTest('test___future__.py', core=True), + RegrTest('test__locale.py'), + RegrTest('test_aepack.py', skip=True), + RegrTest('test_al.py', skip=True), + RegrTest('test_anydbm.py'), + RegrTest('test_applesingle.py', skip=True), + RegrTest('test_array.py', core=True, usemodules='struct'), + RegrTest('test_asynchat.py', usemodules='thread'), + RegrTest('test_atexit.py', core=True), + RegrTest('test_audioop.py'), + RegrTest('test_augassign.py', core=True), + RegrTest('test_base64.py'), + RegrTest('test_bastion.py'), + RegrTest('test_binascii.py'), + + RegrTest('test_binhex.py'), + + RegrTest('test_binop.py', core=True), + RegrTest('test_bisect.py', core=True), + RegrTest('test_bool.py', core=True), + RegrTest('test_bsddb.py', skip="unsupported extension module"), + RegrTest('test_bsddb185.py', skip="unsupported extension module"), + RegrTest('test_bsddb3.py', skip="unsupported extension module"), + RegrTest('test_bufio.py', core=True), + RegrTest('test_builtin.py', core=True), + RegrTest('test_bz2.py', usemodules='bz2'), + RegrTest('test_calendar.py'), + RegrTest('test_call.py', core=True), + RegrTest('test_capi.py'), + RegrTest('test_cd.py', skip=True), + RegrTest('test_cfgparser.py'), + + RegrTest('test_cgi.py'), + RegrTest('test_charmapcodec.py', core=True), + RegrTest('test_cl.py', skip=True), + RegrTest('test_class.py', core=True), + RegrTest('test_cmath.py', core=True), + RegrTest('test_codeccallbacks.py', core=True), + RegrTest('test_codecencodings_cn.py', skip="encodings not available"), + RegrTest('test_codecencodings_hk.py', skip="encodings not available"), + RegrTest('test_codecencodings_jp.py', skip="encodings not available"), + RegrTest('test_codecencodings_kr.py', skip="encodings not available"), + RegrTest('test_codecencodings_tw.py', skip="encodings not available"), + + RegrTest('test_codecmaps_cn.py', skip="encodings not available"), + RegrTest('test_codecmaps_hk.py', skip="encodings not available"), + RegrTest('test_codecmaps_jp.py', skip="encodings not available"), + RegrTest('test_codecmaps_kr.py', skip="encodings not available"), + RegrTest('test_codecmaps_tw.py', skip="encodings not available"), + RegrTest('test_codecs.py', core=True), + RegrTest('test_codeop.py', core=True), + RegrTest('test_coercion.py', core=True), - RegrTest('test_colorsys.py', enabled=True), - RegrTest('test_commands.py', enabled=True), - RegrTest('test_compare.py', enabled=True, core=True), - RegrTest('test_compile.py', enabled=True, core=True), - RegrTest('test_compiler.py', enabled=True, core=False), # this test tests the compiler package from stdlib - RegrTest('test_complex.py', enabled=True, core=True), - - RegrTest('test_contains.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_cookie.py', enabled=False), - RegrTest('test_cookielib.py', enabled=False), - RegrTest('test_copy.py', enabled=True, core=True), - RegrTest('test_copy_reg.py', enabled=True, core=True), - RegrTest('test_cpickle.py', enabled=True, core=True), - RegrTest('test_crypt.py', usemodules='crypt', enabled=False, dumbtest=1), - RegrTest('test_csv.py', enabled=False), - #rev 10840: ImportError: _csv - - RegrTest('test_curses.py', enabled=False, dumbtest=1), - RegrTest('test_datetime.py', enabled=True), - RegrTest('test_dbm.py', enabled=False, dumbtest=1), - RegrTest('test_decimal.py', enabled=True), - RegrTest('test_decorators.py', enabled=True, core=True), - RegrTest('test_deque.py', enabled=True, core=True), - RegrTest('test_descr.py', enabled=True, core=True, usemodules='_weakref'), - RegrTest('test_descrtut.py', enabled=True, core=True), - RegrTest('test_dict.py', enabled=True, core=True), - - RegrTest('test_difflib.py', enabled=True, dumbtest=1), - RegrTest('test_dircache.py', enabled=True, core=True), - RegrTest('test_dis.py', enabled=True), - RegrTest('test_distutils.py', enabled=True), - RegrTest('test_dl.py', enabled=False, dumbtest=1), - RegrTest('test_doctest.py', usemodules="thread", enabled=True), - RegrTest('test_doctest2.py', enabled=True), - RegrTest('test_dumbdbm.py', enabled=True), - RegrTest('test_dummy_thread.py', enabled=True, core=True), - RegrTest('test_dummy_threading.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_email.py', enabled=False), - #rev 10840: Uncaught interp-level exception - - RegrTest('test_email_codecs.py', enabled=False, dumbtest=1), - RegrTest('test_enumerate.py', enabled=True, core=True), - RegrTest('test_eof.py', enabled=True, core=True), - - RegrTest('test_errno.py', enabled=True, dumbtest=1), - RegrTest('test_exceptions.py', enabled=True, core=True), - RegrTest('test_extcall.py', enabled=True, core=True), - RegrTest('test_fcntl.py', enabled=False, dumbtest=1, usemodules='fcntl'), - RegrTest('test_file.py', enabled=True, dumbtest=1, usemodules="posix", core=True), - RegrTest('test_filecmp.py', enabled=True, core=True), - RegrTest('test_fileinput.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_fnmatch.py', enabled=True, core=True), - RegrTest('test_fork1.py', enabled=False, dumbtest=1), - RegrTest('test_format.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_fpformat.py', enabled=True, core=True), - RegrTest('test_frozen.py', enabled=False), - RegrTest('test_funcattrs.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_future.py', enabled=True, core=True), - RegrTest('test_future1.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_future2.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_future3.py', enabled=True, core=True), - RegrTest('test_gc.py', enabled=True, dumbtest=1, usemodules='_weakref'), - RegrTest('test_gdbm.py', enabled=False, dumbtest=1), - RegrTest('test_generators.py', enabled=True, core=True, usemodules='thread _weakref'), - #rev 10840: 30 of 152 tests fail - RegrTest('test_genexps.py', enabled=True, core=True, usemodules='_weakref'), - RegrTest('test_getargs.py', enabled=False, dumbtest=1), - RegrTest('test_getargs2.py', enabled=False), - #rev 10840: ImportError: _testcapi - - RegrTest('test_getopt.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_gettext.py', enabled=False), - #rev 10840: 28 of 28 tests fail - - RegrTest('test_gl.py', enabled=False, dumbtest=1), - RegrTest('test_glob.py', enabled=True, core=True), - RegrTest('test_global.py', enabled=True, core=True), - RegrTest('test_grammar.py', enabled=True, core=True), - RegrTest('test_grp.py', enabled=False), - #rev 10840: ImportError: grp - - RegrTest('test_gzip.py', enabled=False, dumbtest=1), - RegrTest('test_hash.py', enabled=True, core=True), - RegrTest('test_hashlib.py', enabled=True, core=True), - # test_hashlib comes from 2.5 + RegrTest('test_colorsys.py'), + RegrTest('test_commands.py'), + RegrTest('test_compare.py', core=True), + RegrTest('test_compile.py', core=True), + RegrTest('test_compiler.py', core=False), + RegrTest('test_complex.py', core=True), + + RegrTest('test_contains.py', core=True), + RegrTest('test_cookie.py'), + RegrTest('test_cookielib.py'), + RegrTest('test_copy.py', core=True), + RegrTest('test_copy_reg.py', core=True), + RegrTest('test_cpickle.py', core=True), + RegrTest('test_crypt.py', usemodules='crypt'), + RegrTest('test_csv.py', skip="unsupported extension module"), + + RegrTest('test_curses.py', skip="unsupported extension module"), + RegrTest('test_datetime.py'), + RegrTest('test_dbm.py', skip="unsupported extension module"), + RegrTest('test_decimal.py'), + RegrTest('test_decorators.py', core=True), + RegrTest('test_deque.py', core=True), + RegrTest('test_descr.py', core=True, usemodules='_weakref'), + RegrTest('test_descrtut.py', core=True), + RegrTest('test_dict.py', core=True), + + RegrTest('test_difflib.py'), + RegrTest('test_dircache.py', core=True), + RegrTest('test_dis.py'), + RegrTest('test_distutils.py'), + RegrTest('test_dl.py', skip=True), + RegrTest('test_doctest.py', usemodules="thread"), + RegrTest('test_doctest2.py'), + RegrTest('test_dumbdbm.py'), + RegrTest('test_dummy_thread.py', core=True), + RegrTest('test_dummy_threading.py', core=True), + RegrTest('test_email.py'), + + RegrTest('test_email_codecs.py'), + RegrTest('test_enumerate.py', core=True), + RegrTest('test_eof.py', core=True), + + RegrTest('test_errno.py'), + RegrTest('test_exceptions.py', core=True), + RegrTest('test_extcall.py', core=True), + RegrTest('test_fcntl.py', usemodules='fcntl'), + RegrTest('test_file.py', usemodules="posix", core=True), + RegrTest('test_filecmp.py', core=True), + RegrTest('test_fileinput.py', core=True), + RegrTest('test_fnmatch.py', core=True), + RegrTest('test_fork1.py'), + RegrTest('test_format.py', core=True), + RegrTest('test_fpformat.py', core=True), + RegrTest('test_frozen.py', skip="unsupported extension module"), + RegrTest('test_funcattrs.py', core=True), + RegrTest('test_future.py', core=True), + RegrTest('test_future1.py', core=True), + RegrTest('test_future2.py', core=True), + RegrTest('test_future3.py', core=True), + RegrTest('test_gc.py', usemodules='_weakref'), + RegrTest('test_gdbm.py', skip="unsupported extension module"), + RegrTest('test_generators.py', core=True, usemodules='thread _weakref'), + RegrTest('test_genexps.py', core=True, usemodules='_weakref'), + RegrTest('test_getargs.py', skip="unsupported extension module"), + RegrTest('test_getargs2.py', skip="unsupported extension module"), + + RegrTest('test_getopt.py', core=True), + RegrTest('test_gettext.py'), + + RegrTest('test_gl.py', skip=True), + RegrTest('test_glob.py', core=True), + RegrTest('test_global.py', core=True), + RegrTest('test_grammar.py', core=True), + RegrTest('test_grp.py', skip="unsupported extension module"), + + RegrTest('test_gzip.py'), + RegrTest('test_hash.py', core=True), + RegrTest('test_hashlib.py', core=True), - RegrTest('test_heapq.py', enabled=True, core=True), - RegrTest('test_hexoct.py', enabled=True, core=True), - RegrTest('test_hmac.py', enabled=True), - RegrTest('test_hotshot.py', enabled=False), - #rev 10840: ImportError: _hotshot - - RegrTest('test_htmllib.py', enabled=True), - RegrTest('test_htmlparser.py', enabled=True), - RegrTest('test_httplib.py', enabled=True), - RegrTest('test_imageop.py', enabled=False, dumbtest=1), - RegrTest('test_imaplib.py', enabled=True, dumbtest=1), - RegrTest('test_imgfile.py', enabled=False, dumbtest=1), - RegrTest('test_imp.py', enabled=True, core=True, usemodules='thread'), - RegrTest('test_import.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_importhooks.py', enabled=True, core=True), - RegrTest('test_inspect.py', enabled=True, dumbtest=1), - RegrTest('test_ioctl.py', enabled=False), - RegrTest('test_isinstance.py', enabled=True, core=True), - RegrTest('test_iter.py', enabled=True, core=True), - #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser - RegrTest('test_iterlen.py', enabled=True, core=True), - RegrTest('test_itertools.py', enabled=True, core=True), - # modified version in pypy/lib/test2 - - RegrTest('test_largefile.py', enabled=True, dumbtest=1), - RegrTest('test_linuxaudiodev.py', enabled=False), - RegrTest('test_list.py', enabled=True, core=True), - RegrTest('test_locale.py', enabled=False, dumbtest=1), - RegrTest('test_logging.py', enabled=False, usemodules='thread'), - RegrTest('test_long.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_long_future.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_longexp.py', enabled=True, core=True), - RegrTest('test_macfs.py', enabled=False), - RegrTest('test_macostools.py', enabled=False), - RegrTest('test_macpath.py', enabled=True), - RegrTest('test_mailbox.py', enabled=True), - RegrTest('test_marshal.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_math.py', enabled=True, core=True, usemodules='math'), - RegrTest('test_md5.py', enabled=False), - RegrTest('test_mhlib.py', enabled=True), - RegrTest('test_mimetools.py', enabled=True), - RegrTest('test_mimetypes.py', enabled=True), - RegrTest('test_MimeWriter.py', enabled=True, core=False), - RegrTest('test_minidom.py', enabled=False, dumbtest=1), - RegrTest('test_mmap.py', enabled=False), - RegrTest('test_module.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_multibytecodec.py', enabled=True), - RegrTest('test_multibytecodec_support.py', enabled=True, core=True), - RegrTest('test_multifile.py', enabled=True), - RegrTest('test_mutants.py', enabled=True, dumbtest=1, core="possibly"), - RegrTest('test_netrc.py', enabled=True), - RegrTest('test_new.py', enabled=True, core=True), - RegrTest('test_nis.py', enabled=False), - RegrTest('test_normalization.py', enabled=False), - RegrTest('test_ntpath.py', enabled=True, dumbtest=1), - RegrTest('test_opcodes.py', enabled=True, core=True), - RegrTest('test_openpty.py', enabled=False), - RegrTest('test_operations.py', enabled=True, core=True), - RegrTest('test_operator.py', enabled=True, core=True), - RegrTest('test_optparse.py', enabled=False), - # this test fails because it expects that PyPy's builtin - # functions act as if they are staticmethods that can be put - # on classes and don't get bound etc.pp. - - RegrTest('test_os.py', enabled=True, core=True), - RegrTest('test_ossaudiodev.py', enabled=False), - RegrTest('test_parser.py', enabled=True, core=True), - #rev 10840: 18 of 18 tests fail - - RegrTest('test_peepholer.py', enabled=True), - RegrTest('test_pep247.py', enabled=False, dumbtest=1), - RegrTest('test_pep263.py', enabled=True, dumbtest=1), - RegrTest('test_pep277.py', enabled=False), - # XXX this test is _also_ an output test, damn it - # seems to be the only one that invokes run_unittest - # and is an unittest - RegrTest('test_pep292.py', enabled=True), - RegrTest('test_pickle.py', enabled=True, core=True), - RegrTest('test_pickletools.py', enabled=True, dumbtest=1, core=False), - RegrTest('test_pkg.py', enabled=True, core=True), - RegrTest('test_pkgimport.py', enabled=True, core=True), - RegrTest('test_plistlib.py', enabled=False), - RegrTest('test_poll.py', enabled=False), - RegrTest('test_popen.py', enabled=True), - RegrTest('test_popen2.py', enabled=True), - RegrTest('test_posix.py', enabled=True), - RegrTest('test_posixpath.py', enabled=True), - RegrTest('test_pow.py', enabled=True, core=True), - RegrTest('test_pprint.py', enabled=True, core=True), - RegrTest('test_profile.py', enabled=True), - RegrTest('test_profilehooks.py', enabled=True, core=True), - RegrTest('test_pty.py', enabled=False), - RegrTest('test_pwd.py', enabled=False), - #rev 10840: ImportError: pwd - - RegrTest('test_pyclbr.py', enabled=False), - RegrTest('test_pyexpat.py', enabled=False), - RegrTest('test_queue.py', enabled=False, dumbtest=1), - RegrTest('test_quopri.py', enabled=True), - RegrTest('test_random.py', enabled=False), - #rev 10840: Uncaught app-level exception: - #class WichmannHill_TestBasicOps(TestBasicOps): - #File "test_random.py", line 125 in WichmannHill_TestBasicOps - #gen = random.WichmannHill() - #AttributeError: 'module' object has no attribute 'WichmannHill' - - RegrTest('test_re.py', enabled=True, core=True), - - RegrTest('test_repr.py', enabled=True, core=True), - #rev 10840: 6 of 12 tests fail. Always minor stuff like - #'' != '' - - RegrTest('test_resource.py', enabled=False), - RegrTest('test_rfc822.py', enabled=True), - RegrTest('test_rgbimg.py', enabled=False), - RegrTest('test_richcmp.py', enabled=True, core=True), - #rev 10840: 1 of 11 test fails. The failing one had an infinite recursion. - - RegrTest('test_robotparser.py', enabled=True), - RegrTest('test_sax.py', enabled=False, dumbtest=1), - RegrTest('test_scope.py', enabled=True, core=True), - RegrTest('test_scriptpackages.py', enabled=False), - RegrTest('test_select.py', enabled=False, dumbtest=1), - RegrTest('test_set.py', enabled=True, core=True), - RegrTest('test_sets.py', enabled=True), - RegrTest('test_sgmllib.py', enabled=True), - RegrTest('test_sha.py', enabled=True), - # one test is taken out (too_slow_test_case_3), rest passses - RegrTest('test_shelve.py', enabled=True), - RegrTest('test_shlex.py', enabled=True), - RegrTest('test_shutil.py', enabled=True), - RegrTest('test_signal.py', enabled=False), - RegrTest('test_site.py', enabled=False, core=False), # considered cpython impl-detail - # Needs non-faked codecs. - RegrTest('test_slice.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_socket.py', enabled=False, usemodules='thread _weakref'), - - RegrTest('test_socket_ssl.py', enabled=False), - RegrTest('test_socketserver.py', enabled=False, usemodules='thread'), - - RegrTest('test_softspace.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_sort.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_str.py', enabled=True, core=True), - #rev 10840: at least two tests fail, after several hours I gave up waiting for the rest - - RegrTest('test_strftime.py', enabled=False, dumbtest=1), - RegrTest('test_string.py', enabled=True, core=True), - RegrTest('test_StringIO.py', enabled=True, core=True, usemodules='cStringIO'), - RegrTest('test_stringprep.py', enabled=True, dumbtest=1), - RegrTest('test_strop.py', enabled=False), - #rev 10840: ImportError: strop - - RegrTest('test_strptime.py', enabled=False), - #rev 10840: 1 of 42 test fails: seems to be some regex problem - - RegrTest('test_struct.py', enabled=True, dumbtest=1, usemodules='struct'), - RegrTest('test_structseq.py', enabled=False, dumbtest=1), - RegrTest('test_subprocess.py', enabled=False, usemodules='signal'), - RegrTest('test_sunaudiodev.py', enabled=False, dumbtest=1), - RegrTest('test_sundry.py', enabled=False, dumbtest=1), - # test_support is not a test - RegrTest('test_symtable.py', enabled=False, dumbtest=1), - RegrTest('test_syntax.py', enabled=True, core=True), - RegrTest('test_sys.py', enabled=True, core=True), - RegrTest('test_tcl.py', enabled=False), - RegrTest('test_tarfile.py', enabled=False), - #rev 10840: 13 of 13 test fail - - RegrTest('test_tempfile.py', enabled=False), - # tempfile does: class ... unlink = _os.unlink!!! - #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser - - RegrTest('test_textwrap.py', enabled=True), - RegrTest('test_thread.py', enabled=True, usemodules="thread", core=True), - RegrTest('test_threaded_import.py', usemodules="thread", enabled=True, core=True), + RegrTest('test_heapq.py', core=True), + RegrTest('test_hexoct.py', core=True), + RegrTest('test_hmac.py'), + RegrTest('test_hotshot.py', skip="unsupported extension module"), + + RegrTest('test_htmllib.py'), + RegrTest('test_htmlparser.py'), + RegrTest('test_httplib.py'), + RegrTest('test_imageop.py', skip="unsupported extension module"), + RegrTest('test_imaplib.py'), + RegrTest('test_imgfile.py', skip="unsupported extension module"), + RegrTest('test_imp.py', core=True, usemodules='thread'), + RegrTest('test_import.py', core=True), + RegrTest('test_importhooks.py', core=True), + RegrTest('test_inspect.py'), + RegrTest('test_ioctl.py'), + RegrTest('test_isinstance.py', core=True), + RegrTest('test_iter.py', core=True), + RegrTest('test_iterlen.py', core=True), + RegrTest('test_itertools.py', core=True), + + RegrTest('test_largefile.py'), + RegrTest('test_linuxaudiodev.py', skip="unsupported extension module"), + RegrTest('test_list.py', core=True), + RegrTest('test_locale.py'), + RegrTest('test_logging.py', usemodules='thread'), + RegrTest('test_long.py', core=True), + RegrTest('test_long_future.py', core=True), + RegrTest('test_longexp.py', core=True), + RegrTest('test_macfs.py', skip=True), + RegrTest('test_macostools.py', skip=True), + RegrTest('test_macpath.py'), + RegrTest('test_mailbox.py'), + RegrTest('test_marshal.py', core=True), + RegrTest('test_math.py', core=True, usemodules='math'), + RegrTest('test_md5.py'), + RegrTest('test_mhlib.py'), + RegrTest('test_mimetools.py'), + RegrTest('test_mimetypes.py'), + RegrTest('test_MimeWriter.py', core=False), + RegrTest('test_minidom.py'), + RegrTest('test_mmap.py'), + RegrTest('test_module.py', core=True), + RegrTest('test_multibytecodec.py'), + RegrTest('test_multibytecodec_support.py', core=True), + RegrTest('test_multifile.py'), + RegrTest('test_mutants.py', core="possibly"), + RegrTest('test_netrc.py'), + RegrTest('test_new.py', core=True), + RegrTest('test_nis.py', skip="unsupported extension module"), + RegrTest('test_normalization.py'), + RegrTest('test_ntpath.py'), + RegrTest('test_opcodes.py', core=True), + RegrTest('test_openpty.py', skip="unsupported extension module"), + RegrTest('test_operations.py', core=True), + RegrTest('test_operator.py', core=True), + RegrTest('test_optparse.py'), + + RegrTest('test_os.py', core=True), + RegrTest('test_ossaudiodev.py', skip="unsupported extension module"), + RegrTest('test_parser.py', core=True), + + RegrTest('test_peepholer.py'), + RegrTest('test_pep247.py'), + RegrTest('test_pep263.py'), + RegrTest('test_pep277.py'), + RegrTest('test_pep292.py'), + RegrTest('test_pickle.py', core=True), + RegrTest('test_pickletools.py', core=False), + RegrTest('test_pkg.py', core=True), + RegrTest('test_pkgimport.py', core=True), + RegrTest('test_plistlib.py'), + RegrTest('test_poll.py'), + RegrTest('test_popen.py'), + RegrTest('test_popen2.py'), + RegrTest('test_posix.py'), + RegrTest('test_posixpath.py'), + RegrTest('test_pow.py', core=True), + RegrTest('test_pprint.py', core=True), + RegrTest('test_profile.py'), + RegrTest('test_profilehooks.py', core=True), + RegrTest('test_pty.py', skip="unsupported extension module"), + RegrTest('test_pwd.py', skip="unsupported extension module"), + + RegrTest('test_pyclbr.py'), + RegrTest('test_pyexpat.py'), + RegrTest('test_queue.py'), + RegrTest('test_quopri.py'), + RegrTest('test_random.py'), + RegrTest('test_re.py', core=True), + + RegrTest('test_repr.py', core=True), + RegrTest('test_resource.py', skip="unsupported extension module"), + RegrTest('test_rfc822.py'), + RegrTest('test_rgbimg.py', skip="unsupported extension module"), + RegrTest('test_richcmp.py', core=True), + + RegrTest('test_robotparser.py'), + RegrTest('test_sax.py'), + RegrTest('test_scope.py', core=True), + RegrTest('test_scriptpackages.py', skip="unsupported extension module"), + RegrTest('test_select.py'), + RegrTest('test_set.py', core=True), + RegrTest('test_sets.py'), + RegrTest('test_sgmllib.py'), + RegrTest('test_sha.py'), + RegrTest('test_shelve.py'), + RegrTest('test_shlex.py'), + RegrTest('test_shutil.py'), + RegrTest('test_signal.py'), + RegrTest('test_site.py', core=False), + RegrTest('test_slice.py', core=True), + RegrTest('test_socket.py', usemodules='thread _weakref'), + + RegrTest('test_socket_ssl.py', skip="no ssl support yet"), + RegrTest('test_socketserver.py', usemodules='thread'), + + RegrTest('test_softspace.py', core=True), + RegrTest('test_sort.py', core=True), + RegrTest('test_str.py', core=True), + + RegrTest('test_strftime.py'), + RegrTest('test_string.py', core=True), + RegrTest('test_StringIO.py', core=True, usemodules='cStringIO'), + RegrTest('test_stringprep.py'), + RegrTest('test_strop.py', skip="deprecated"), + + RegrTest('test_strptime.py'), + + RegrTest('test_struct.py', usemodules='struct'), + RegrTest('test_structseq.py'), + RegrTest('test_subprocess.py', usemodules='signal'), + RegrTest('test_sunaudiodev.py', skip=True), + RegrTest('test_sundry.py'), + RegrTest('test_symtable.py', skip="implementation detail"), + RegrTest('test_syntax.py', core=True), + RegrTest('test_sys.py', core=True), + RegrTest('test_tcl.py', skip="unsupported extension module"), + RegrTest('test_tarfile.py'), + + RegrTest('test_tempfile.py'), + + RegrTest('test_textwrap.py'), + RegrTest('test_thread.py', usemodules="thread", core=True), + RegrTest('test_threaded_import.py', usemodules="thread", core=True), RegrTest('test_threadedtempfile.py', - usemodules="thread", enabled=True, core=False), # tempfile is non-core by itself - #rev 10840: ImportError: thread + usemodules="thread", core=False), - RegrTest('test_threading.py', usemodules="thread", enabled=True, dumbtest=1, core=True), - #rev 10840: ImportError: thread - RegrTest('test_threading_local.py', usemodules="thread", enabled=True, dumbtest=1, core=True), - RegrTest('test_threadsignals.py', usemodules="thread", enabled=False, dumbtest=1), - - RegrTest('test_time.py', enabled=True, core=True), - RegrTest('test_timeout.py', enabled=False), - #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser - - RegrTest('test_tokenize.py', enabled=False), - RegrTest('test_trace.py', enabled=True, core=True), - RegrTest('test_traceback.py', enabled=True, core=True), - #rev 10840: 2 of 2 tests fail - RegrTest('test_transformer.py', enabled=True, core=True), - RegrTest('test_tuple.py', enabled=True, core=True), - - RegrTest('test_types.py', enabled=True, core=True), - #rev 11598: one of the mod related to dict iterators is questionable - # and questions whether how we implement them is meaningful in the - # long run + RegrTest('test_threading.py', usemodules="thread", core=True), + RegrTest('test_threading_local.py', usemodules="thread", core=True), + RegrTest('test_threadsignals.py', usemodules="thread"), + + RegrTest('test_time.py', core=True), + RegrTest('test_timeout.py'), + + RegrTest('test_tokenize.py'), + RegrTest('test_trace.py', core=True), + RegrTest('test_traceback.py', core=True), + RegrTest('test_transformer.py', core=True), + RegrTest('test_tuple.py', core=True), + + RegrTest('test_types.py', core=True), - RegrTest('test_ucn.py', enabled=False), - RegrTest('test_unary.py', enabled=True, core=True), - RegrTest('test_unicode.py', enabled=True, core=True), - RegrTest('test_unicode_file.py', enabled=False), - RegrTest('test_unicodedata.py', enabled=False), - RegrTest('test_unittest.py', enabled=True, core=True), - RegrTest('test_univnewlines.py', enabled=True, core=True), - RegrTest('test_unpack.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_urllib.py', enabled=True), - RegrTest('test_urllib2.py', enabled=True, dumbtest=1), - RegrTest('test_urllib2net.py', enabled=True), - RegrTest('test_urllibnet.py', enabled=False), - # try to understand failure!!! - RegrTest('test_urlparse.py', enabled=True), - RegrTest('test_userdict.py', enabled=True, core=True), - RegrTest('test_userlist.py', enabled=True, core=True), - RegrTest('test_userstring.py', enabled=True, core=True), - RegrTest('test_uu.py', enabled=False), - #rev 10840: 1 of 9 test fails - - RegrTest('test_warnings.py', enabled=True, core=True), - RegrTest('test_wave.py', enabled=False, dumbtest=1), - RegrTest('test_weakref.py', enabled=True, core=True, usemodules='_weakref'), - - RegrTest('test_whichdb.py', enabled=True), - RegrTest('test_winreg.py', enabled=False), - RegrTest('test_winsound.py', enabled=False), - RegrTest('test_xmllib.py', enabled=False), - RegrTest('test_xmlrpc.py', enabled=False), - #rev 10840: 2 of 5 tests fail - - RegrTest('test_xpickle.py', enabled=False), - RegrTest('test_xrange.py', enabled=True, core=True), - RegrTest('test_zipfile.py', enabled=False, dumbtest=1), - RegrTest('test_zipimport.py', enabled=True, usemodules='zlib zipimport'), - RegrTest('test_zlib.py', enabled=True, usemodules='zlib'), - - # new test files from 2.5 - RegrTest('test_ast.py', enabled=True), - RegrTest('test_bigaddrspace.py', enabled=True), - RegrTest('test_bigmem.py', enabled=True), - RegrTest('test_cProfile.py', enabled=True), - RegrTest('test_cmd_line.py', enabled=True), - RegrTest('test_code.py', enabled=True), - RegrTest('test_coding.py', enabled=True), - RegrTest('test_complex_args.py', enabled=True), - RegrTest('test_contextlib.py', enabled=True), - RegrTest('test_ctypes.py', enabled=True), - RegrTest('test_defaultdict.py', enabled=True), - RegrTest('test_email_renamed.py', enabled=True), - RegrTest('test_exception_variations.py', enabled=True), - RegrTest('test_float.py', enabled=True), - RegrTest('test_functools.py', enabled=True), - RegrTest('test_index.py', enabled=True), - RegrTest('test_old_mailbox.py', enabled=True), - RegrTest('test_pep352.py', enabled=True), - RegrTest('test_platform.py', enabled=True), - RegrTest('test_runpy.py', enabled=True), - RegrTest('test_sqlite.py', enabled=True), - RegrTest('test_startfile.py', enabled=True), - RegrTest('test_structmembers.py', enabled=True), - RegrTest('test_urllib2_localnet.py', enabled=True), - RegrTest('test_uuid.py', enabled=True), - RegrTest('test_wait3.py', enabled=True), - RegrTest('test_wait4.py', enabled=True), - RegrTest('test_with.py', enabled=True), - RegrTest('test_wsgiref.py', enabled=True), - RegrTest('test_xdrlib.py', enabled=True), - RegrTest('test_xml_etree.py', enabled=True), - RegrTest('test_xml_etree_c.py', enabled=True), - RegrTest('test_zipfile64.py', enabled=True), + RegrTest('test_ucn.py'), + RegrTest('test_unary.py', core=True), + RegrTest('test_unicode.py', core=True), + RegrTest('test_unicode_file.py'), + RegrTest('test_unicodedata.py'), + RegrTest('test_unittest.py', core=True), + RegrTest('test_univnewlines.py', core=True), + RegrTest('test_unpack.py', core=True), + RegrTest('test_urllib.py'), + RegrTest('test_urllib2.py'), + RegrTest('test_urllib2net.py'), + RegrTest('test_urllibnet.py'), + RegrTest('test_urlparse.py'), + RegrTest('test_userdict.py', core=True), + RegrTest('test_userlist.py', core=True), + RegrTest('test_userstring.py', core=True), + RegrTest('test_uu.py'), + + RegrTest('test_warnings.py', core=True), + RegrTest('test_wave.py', skip="unsupported extension module"), + RegrTest('test_weakref.py', core=True, usemodules='_weakref'), + + RegrTest('test_whichdb.py'), + RegrTest('test_winreg.py', skip="unsupported extension module"), + RegrTest('test_winsound.py', skip="unsupported extension module"), + RegrTest('test_xmllib.py'), + RegrTest('test_xmlrpc.py'), + + RegrTest('test_xpickle.py'), + RegrTest('test_xrange.py', core=True), + RegrTest('test_zipfile.py'), + RegrTest('test_zipimport.py', usemodules='zlib zipimport'), + RegrTest('test_zlib.py', usemodules='zlib'), + + RegrTest('test_ast.py'), + RegrTest('test_bigaddrspace.py'), + RegrTest('test_bigmem.py'), + RegrTest('test_cProfile.py'), + RegrTest('test_cmd_line.py'), + RegrTest('test_code.py'), + RegrTest('test_coding.py'), + RegrTest('test_complex_args.py'), + RegrTest('test_contextlib.py'), + RegrTest('test_ctypes.py'), + RegrTest('test_defaultdict.py'), + RegrTest('test_email_renamed.py'), + RegrTest('test_exception_variations.py'), + RegrTest('test_float.py'), + RegrTest('test_functools.py'), + RegrTest('test_index.py'), + RegrTest('test_old_mailbox.py'), + RegrTest('test_pep352.py'), + RegrTest('test_platform.py'), + RegrTest('test_runpy.py'), + RegrTest('test_sqlite.py'), + RegrTest('test_startfile.py'), + RegrTest('test_structmembers.py'), + RegrTest('test_urllib2_localnet.py'), + RegrTest('test_uuid.py'), + RegrTest('test_wait3.py'), + RegrTest('test_wait4.py'), + RegrTest('test_with.py'), + RegrTest('test_wsgiref.py'), + RegrTest('test_xdrlib.py'), + RegrTest('test_xml_etree.py'), + RegrTest('test_xml_etree_c.py'), + RegrTest('test_zipfile64.py'), ] def check_testmap_complete(): @@ -546,7 +488,7 @@ for path in regrtestdir.listdir(fil='test_*.py'): name = path.basename if name not in listed_names: - missing.append(' RegrTest(%r, enabled=True),' % (name,)) + missing.append(' RegrTest(%r),' % (name,)) missing.sort() assert not missing, "non-listed tests:\n%s" % ('\n'.join(missing),) check_testmap_complete() From iko at codespeak.net Wed Oct 8 18:05:02 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Wed, 8 Oct 2008 18:05:02 +0200 (CEST) Subject: [pypy-svn] r58839 - in pypy/branch/2.5-merge/pypy/lib: . app_test Message-ID: <20081008160502.985FA169E9A@codespeak.net> Author: iko Date: Wed Oct 8 18:05:02 2008 New Revision: 58839 Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py pypy/branch/2.5-merge/pypy/lib/collections.py Log: fix defaultdict recursive repr() Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py (original) +++ pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py Wed Oct 8 18:05:02 2008 @@ -68,6 +68,17 @@ d3[13] assert repr(d3), "defaultdict(%s, {13: 43})" % repr(foo) + def test_recursive_repr(self): + # Issue2045: stack overflow when default_factory is a bound method + class sub(defaultdict): + def __init__(self): + self.default_factory = self._factory + def _factory(self): + return [] + d = sub() + assert repr(d).startswith( + "defaultdict( Author: pedronis Date: Wed Oct 8 18:09:11 2008 New Revision: 58840 Modified: pypy/build/bot2/pypybuildbot/master.py Log: adding of bigdogvm1, don't use it for own tests for now Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Wed Oct 8 18:09:11 2008 @@ -47,7 +47,7 @@ "factory": pypyOwnTestFactory }, {"name": "pypy-c-lib-python-linux-x86-32", - "slavenames": ["wyvern", "cobra"], + "slavenames": ["wyvern", "cobra", "bigdogvm1"], "builddir": "pypy-c-lib-python-linux-x86-32", "factory": pypyTranslatedLibPythonTestFactory }, From pedronis at codespeak.net Wed Oct 8 18:24:42 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 18:24:42 +0200 (CEST) Subject: [pypy-svn] r58841 - pypy/build/bot2/pypybuildbot Message-ID: <20081008162442.7CAF9169ECB@codespeak.net> Author: pedronis Date: Wed Oct 8 18:24:40 2008 New Revision: 58841 Modified: pypy/build/bot2/pypybuildbot/master.py Log: adding a builder for win32 running translation+cpython tests on the pypy-c Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Wed Oct 8 18:24:40 2008 @@ -26,13 +26,19 @@ pypyOwnTestFactoryWin = pypybuilds.PyPyOwnTestFactory(platform="win32") pypyTranslatedLibPythonTestFactory = pypybuilds.PyPyTranslaledLibPythonTestFactory() +pypyTranslatedLibPythonTestFactoryWin = pypybuilds.PyPyTranslaledLibPythonTestFactory(platform="win32") + + +LINUX32 = "own-linux-x86-32" +CPYLINUX32 = "pypy-c-lib-python-linux-x86-32" +CPYWIN32 = "pypy-c-lib-python-win-32" BuildmasterConfig = { 'slavePortnum': slavePortnum, 'change_source': [], 'schedulers': [ - Nightly("nightly", ["own-linux-x86-32", "pypy-c-lib-python-linux-x86-32"], hour=4, minute=45), + Nightly("nightly", [LINUX32, CPYLINUX32], hour=4, minute=45), ], 'status': [status], @@ -41,17 +47,21 @@ in passwords.iteritems()], 'builders': [ - {"name": "own-linux-x86-32", + {"name": LINUX32, "slavenames": ["wyvern", "cobra"], - "builddir": "own-linux-x86-32", + "builddir": LINUX2, "factory": pypyOwnTestFactory }, - {"name": "pypy-c-lib-python-linux-x86-32", + {"name": CPYLINUX32, "slavenames": ["wyvern", "cobra", "bigdogvm1"], - "builddir": "pypy-c-lib-python-linux-x86-32", + "builddir": CPYLINUX32, "factory": pypyTranslatedLibPythonTestFactory }, - + {"name": CPYWIN32, + "slavenames": ["winxp32-py2.5"], + "builddir": CPYWIN32, + "factory": pypyTranslatedLibPythonTestFactoryWin + }, ], 'buildbotURL': 'http://codespeak.net:%d/'%(httpPortNumber), From pedronis at codespeak.net Wed Oct 8 18:26:03 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 18:26:03 +0200 (CEST) Subject: [pypy-svn] r58842 - pypy/build/bot2/pypybuildbot Message-ID: <20081008162603.64E21169EC8@codespeak.net> Author: pedronis Date: Wed Oct 8 18:26:02 2008 New Revision: 58842 Modified: pypy/build/bot2/pypybuildbot/master.py Log: oops Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Wed Oct 8 18:26:02 2008 @@ -49,7 +49,7 @@ 'builders': [ {"name": LINUX32, "slavenames": ["wyvern", "cobra"], - "builddir": LINUX2, + "builddir": LINUX32, "factory": pypyOwnTestFactory }, {"name": CPYLINUX32, From pedronis at codespeak.net Wed Oct 8 18:28:39 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 8 Oct 2008 18:28:39 +0200 (CEST) Subject: [pypy-svn] r58843 - pypy/build/bot2 Message-ID: <20081008162839.2F28E169EF2@codespeak.net> Author: pedronis Date: Wed Oct 8 18:28:38 2008 New Revision: 58843 Modified: pypy/build/bot2/TODO Log: status Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Wed Oct 8 18:28:38 2008 @@ -16,5 +16,5 @@ - move most buildbots to be over python 2.5 (?) -- wire windows slave +- wire windows slave IN-PROGRESS From arigo at codespeak.net Wed Oct 8 18:32:53 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 18:32:53 +0200 (CEST) Subject: [pypy-svn] r58844 - pypy/dist/pypy/translator/backendopt Message-ID: <20081008163253.F12DB169F18@codespeak.net> Author: arigo Date: Wed Oct 8 18:32:53 2008 New Revision: 58844 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py Log: (fijal, antocuni, arigo) Big refactoring to introduce the VirtualFrame class. No more test passes. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Wed Oct 8 18:32:53 2008 @@ -35,14 +35,23 @@ class RuntimeSpecNode(SpecNode): + def __init__(self, name, TYPE): + self.name = name + self.TYPE = TYPE + + def newvar(self): + v = Variable(self.name) + v.concretetype = self.TYPE + return v + def getfrozenkey(self, memo): return 'R' - def find_rt_nodes(self, memo, result): + def accumulate_rt_nodes(self, memo, result): result.append(self) - def copy(self, function, name, TYPE, memo): - return function(name, TYPE) + def copy(self, memo): + return RuntimeSpecNode(self.name, self.TYPE) def contains_mutable(self): return False @@ -64,22 +73,20 @@ result.append(subnode.getfrozenkey(memo)) return tuple(result) - def find_rt_nodes(self, memo, result): + def accumulate_rt_nodes(self, memo, result): if self in memo: return memo[self] = True for subnode in self.fields: - subnode.find_rt_nodes(memo, result) + subnode.accumulate_rt_nodes(memo, result) - def copy(self, function, _name, _TYPE, memo): + def copy(self, memo): if self in memo: return memo[self] newnode = VirtualSpecNode(self.typedesc, []) memo[self] = newnode - for (name, FIELDTYPE), subnode in zip(self.typedesc.names_and_types, - self.fields): - newsubnode = subnode.copy(function, name, FIELDTYPE, memo) - newnode.fields.append(newsubnode) + for subnode in self.fields: + newnode.fields.append(subnode.copy(memo)) return newnode def contains_mutable(self): @@ -91,16 +98,54 @@ return False -def getfrozenkey(nodelist): - memo = {} - return tuple([node.getfrozenkey(memo) for node in nodelist]) +class VirtualFrame(object): + + def __init__(self, sourceblock, nextopindex, allnodes, callerframe=None): + self.varlist = vars_alive_through_op(sourceblock, nextopindex) + self.nodelist = [allnodes[v] for v in self.varlist] + self.sourceblock = sourceblock + self.nextopindex = nextopindex + self.callerframe = callerframe + + def get_nodes_in_use(self): + return dict(zip(self.varlist, self.nodelist)) + + def copy(self, memo): + newframe = VirtualFrame.__new__(VirtualFrame) + newframe.varlist = self.varlist + newframe.nodelist = [node.copy(memo) for node in self.nodelist] + newframe.sourceblock = self.sourceblock + newframe.nextopindex = self.nextopindex + if self.callerframe is None: + newframe.callerframe = None + else: + newframe.callerframe = self.callerframe.copy(memo) + return newframe + + def enum_call_stack(self): + frame = self + while frame is not None: + yield frame + frame = frame.callerframe + + def getfrozenkey(self): + memo = {} + key = [] + for frame in self.enum_call_stack(): + key.append(frame.sourceblock) + key.append(frame.nextopindex) + for node in frame.nodelist: + key.append(node.getfrozenkey(memo)) + return tuple(key) + + def find_rt_nodes(self): + result = [] + memo = {} + for frame in self.enum_call_stack(): + for node in frame.nodelist: + node.accumulate_rt_nodes(memo, result) + return result -def find_rt_nodes(nodelist): - result = [] - memo = {} - for node in nodelist: - node.find_rt_nodes(memo, result) - return result def is_trivial_nodelist(nodelist): for node in nodelist: @@ -180,14 +225,12 @@ class BlockSpecCache(object): def __init__(self, fallback=None): - self.specialized_blocks = {} # {(org Block, frozenkey): spec Block} + self.specialized_blocks = {} # {frame_frozen_key: spec Block} self.graph_starting_at = {} # {spec Block: spec Graph} self.fallback = fallback - def lookup_spec_block(self, orgblock, nodelist): - if is_trivial_nodelist(nodelist): - return orgblock - key = orgblock, getfrozenkey(nodelist) + def lookup_spec_block(self, virtualframe): + key = virtualframe.getfrozenkey() try: return self.specialized_blocks[key] except KeyError: @@ -196,9 +239,8 @@ else: return self.fallback.specialized_blocks.get(key) - def remember_spec_block(self, orgblock, nodelist, specblock): - assert len(nodelist) == len(orgblock.inputargs) - key = orgblock, getfrozenkey(nodelist) + def remember_spec_block(self, virtualframe, specblock): + key = virtualframe.getfrozenkey() self.specialized_blocks[key] = specblock def lookup_graph_starting_at(self, startblock): @@ -229,55 +271,82 @@ def remove_malloc(self, block, v_result): self.startblock = block spec = BlockSpecializer(self, v_result) - trivialnodelist = [RuntimeSpecNode() for v in block.inputargs] - spec.initialize_renamings(block.inputargs, trivialnodelist) - self.newinputargs = spec.expand_vars(block.inputargs) - self.newoperations = spec.specialize_operations(block.operations) + nodes = {} + for v in block.inputargs: + nodes[v] = RuntimeSpecNode(v, v.concretetype) + trivialframe = VirtualFrame(block, 0, nodes) + self.newinputargs = spec.initialize_renamings(trivialframe) + self.newoperations = spec.specialize_operations() self.newexitswitch = spec.rename_nonvirtual(block.exitswitch, 'exitswitch') self.newexits = self.follow_exits(block, spec) def follow_exits(self, block, spec): + currentframe = spec.virtualframe newlinks = [] for link in block.exits: - targetnodes = [spec.getnode(v) for v in link.args] - specblock = self.get_specialized_block(link.target, targetnodes) - newlink = Link(spec.expand_vars(link.args), specblock) + targetnodes = {} + + rtnodes = [] + for v1, v2 in zip(link.args, link.target.inputargs): + node = spec.getnode(v1) + if isinstance(node, RuntimeSpecNode): + rtnodes.append(node) + targetnodes[v2] = node + + if (len(rtnodes) == len(link.args) and + currentframe.callerframe is None): + # there is no more VirtualSpecNodes being passed around, + # so we can stop specializing. + specblock = link.target + else: + newframe = VirtualFrame(link.target, 0, targetnodes, + callerframe=currentframe.callerframe) + rtnodes = newframe.find_rt_nodes() + specblock = self.get_specialized_block(newframe) + + linkargs = [spec.renamings[rtnode] for rtnode in rtnodes] + newlink = Link(linkargs, specblock) newlink.exitcase = link.exitcase newlink.llexitcase = link.llexitcase newlinks.append(newlink) return newlinks - def get_specialized_block(self, orgblock, nodelist): - specblock = self.cache.lookup_spec_block(orgblock, nodelist) + def get_specialized_block(self, virtualframe): + specblock = self.cache.lookup_spec_block(virtualframe) if specblock is None: + orgblock = virtualframe.sourceblock if orgblock.operations == (): raise CannotVirtualize("return or except block") spec = BlockSpecializer(self) - spec.initialize_renamings(orgblock.inputargs, nodelist) - specblock = Block(spec.expand_vars(orgblock.inputargs)) - self.pending_specializations.append((spec, orgblock, specblock)) - self.cache.remember_spec_block(orgblock, nodelist, specblock) + specinputargs = spec.initialize_renamings(virtualframe.copy({})) + specblock = Block(specinputargs) + self.pending_specializations.append((spec, specblock)) + self.cache.remember_spec_block(virtualframe, specblock) return specblock - def get_specialized_graph(self, graph, v): - block = graph.startblock - specblock = self.get_specialized_block(block, v) - if specblock is block: + def get_specialized_graph(self, graph, nodelist): + if is_trivial_nodelist(nodelist): return graph + block = graph.startblock + assert len(graph.getargs()) == len(nodelist) + nodes = dict(zip(graph.getargs(), nodelist)) + virtualframe = VirtualFrame(block, 0, nodes) + specblock = self.get_specialized_block(virtualframe) specgraph = self.cache.lookup_graph_starting_at(specblock) if specgraph is None: - specgraph = FunctionGraph(graph.name + '_spec', specblock) + specgraph = FunctionGraph(graph.name + '_mallocv', specblock) self.cache.remember_graph_starting_at(specblock, specgraph) return specgraph def propagate_specializations(self): while self.pending_specializations: - spec, block, specblock = self.pending_specializations.pop() - specblock.operations = spec.specialize_operations(block.operations) - specblock.exitswitch = spec.rename_nonvirtual(block.exitswitch, - 'exitswitch') - specblock.closeblock(*self.follow_exits(block, spec)) + spec, specblock = self.pending_specializations.pop() + sourceblock = spec.virtualframe.sourceblock + specblock.operations = spec.specialize_operations() + specblock.exitswitch = spec.rename_nonvirtual( + sourceblock.exitswitch, 'exitswitch') + specblock.closeblock(*self.follow_exits(sourceblock, spec)) def commit(self): self.startblock.inputargs = self.newinputargs @@ -293,14 +362,19 @@ self.mallocspec = mallocspec self.v_expand_malloc = v_expand_malloc - def initialize_renamings(self, inputargs, inputnodes): - assert len(inputargs) == len(inputnodes) - self.nodes = {} + def initialize_renamings(self, virtualframe): + # the caller is responsible for making a copy of 'virtualframe' + # if needed, because the BlockSpecializer will mutate some of its + # content. + self.virtualframe = virtualframe + self.nodes = virtualframe.get_nodes_in_use() self.renamings = {} # {RuntimeSpecNode(): Variable()} - memo = {} - for v, node in zip(inputargs, inputnodes): - newnode = node.copy(self.fresh_rtnode, v, v.concretetype, memo) - self.setnode(v, newnode) + result = [] + for rtnode in virtualframe.find_rt_nodes(): + v = rtnode.newvar() + self.renamings[rtnode] = v + result.append(v) + return result def setnode(self, v, node): assert v not in self.nodes @@ -310,7 +384,7 @@ if isinstance(v, Variable): return self.nodes[v] else: - rtnode = RuntimeSpecNode() + rtnode = RuntimeSpecNode('const', v.concretetype) self.renamings[rtnode] = v return rtnode @@ -322,12 +396,15 @@ raise CannotVirtualize(where) return self.renamings[node] - def expand_vars(self, vars): - nodelist = [self.getnode(v) for v in vars] - rtnodes = find_rt_nodes(nodelist) + def expand_nodes(self, nodelist): + memo = {} + rtnodes = [] + for node in nodelist: + node.accumulate_rt_nodes(memo, rtnodes) return [self.renamings[rtnode] for rtnode in rtnodes] - def specialize_operations(self, operations): + def specialize_operations(self): + operations = self.virtualframe.sourceblock.operations newoperations = [] for op in operations: meth = getattr(self, 'handle_op_' + op.opname, @@ -335,17 +412,12 @@ newoperations += meth(op) return newoperations - def fresh_rtnode(self, name, TYPE): - newvar = Variable(name) - newvar.concretetype = TYPE - newrtnode = RuntimeSpecNode() - self.renamings[newrtnode] = newvar - return newrtnode - def make_rt_result(self, v_result): - rtnode = self.fresh_rtnode(v_result, v_result.concretetype) - self.setnode(v_result, rtnode) - return self.renamings[rtnode] + newrtnode = RuntimeSpecNode(v_result, v_result.concretetype) + self.setnode(v_result, newrtnode) + v_new = newrtnode.newvar() + self.renamings[newrtnode] = v_new + return v_new def handle_default(self, op): newargs = [self.rename_nonvirtual(v, op) for v in op.args] @@ -378,7 +450,7 @@ virtualnode = VirtualSpecNode(typedesc, []) self.setnode(op.result, virtualnode) for name, FIELDTYPE in typedesc.names_and_types: - fieldnode = RuntimeSpecNode() + fieldnode = RuntimeSpecNode(name, FIELDTYPE) virtualnode.fields.append(fieldnode) c = Constant(FIELDTYPE._defl()) c.concretetype = FIELDTYPE @@ -396,6 +468,7 @@ assert nb_args == len(graph.getargs()) newnodes = [self.getnode(v) for v in op.args[1:]] if contains_mutable(newnodes): + xxx return self.handle_default(op) newgraph = self.mallocspec.get_specialized_graph(graph, newnodes) if newgraph is graph: @@ -403,7 +476,31 @@ fspecptr = getfunctionptr(newgraph) newargs = [Constant(fspecptr, concretetype=lltype.typeOf(fspecptr))] - newargs += self.expand_vars(op.args[1:]) + newargs += self.expand_nodes(newnodes) newresult = self.make_rt_result(op.result) newop = SpaceOperation('direct_call', newargs, newresult) return [newop] + +# ____________________________________________________________ +# helpers + +def vars_alive_through_op(block, index): + # NB. make sure this always returns the variables in the same order + result = [] + seen = {} + def see(v): + if isinstance(v, Variable) and v not in seen: + result.append(v) + seen[v] = True + # don't include the variables produced by the current or future operations + for op in block.operations[index:]: + seen[op.result] = True + # but include the variables consumed by the current or any future operation + for op in block.operations[index:]: + for v in op.args: + see(v) + see(block.exitswitch) + for link in block.exits: + for v in link.args: + see(v) + return result From cfbolz at codespeak.net Wed Oct 8 18:49:58 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 8 Oct 2008 18:49:58 +0200 (CEST) Subject: [pypy-svn] r58845 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081008164958.5CEEF169EB6@codespeak.net> Author: cfbolz Date: Wed Oct 8 18:49:57 2008 New Revision: 58845 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py Log: (cfbolz, iko, pedronis): make test_support.findfile search files in 2.5.2, not in modified-2.5.2 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py Wed Oct 8 18:49:57 2008 @@ -209,15 +209,18 @@ unlink(TESTFN) del os, fp -def findfile(file, here=__file__): +def findfile(file, here=None): """Try to find a file on sys.path and the working directory. If it is not found the argument passed to the function is returned (this does not necessarily signal failure; could still be the legitimate path).""" - import os + import os, test if os.path.isabs(file): return file path = sys.path - path = [os.path.dirname(here)] + path + if here is None: + path = test.__path__ + path + else: + path = [os.path.dirname(here)] + path for dn in path: fn = os.path.join(dn, file) if os.path.exists(fn): return fn From arigo at codespeak.net Wed Oct 8 19:01:08 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 19:01:08 +0200 (CEST) Subject: [pypy-svn] r58846 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081008170108.082BB16854D@codespeak.net> Author: arigo Date: Wed Oct 8 19:01:08 2008 New Revision: 58846 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: (antocuni, fijal, arigo) Support for inlining calls. Yay :-) Still in-progress. See the future tests... Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Wed Oct 8 19:01:08 2008 @@ -277,12 +277,13 @@ trivialframe = VirtualFrame(block, 0, nodes) self.newinputargs = spec.initialize_renamings(trivialframe) self.newoperations = spec.specialize_operations() - self.newexitswitch = spec.rename_nonvirtual(block.exitswitch, - 'exitswitch') - self.newexits = self.follow_exits(block, spec) + self.newexitswitch, self.newexits = self.follow_exits(spec) - def follow_exits(self, block, spec): + def follow_exits(self, spec): currentframe = spec.virtualframe + block = currentframe.sourceblock + v_exitswitch = spec.rename_nonvirtual(block.exitswitch, + 'exitswitch') newlinks = [] for link in block.exits: targetnodes = {} @@ -310,14 +311,17 @@ newlink.exitcase = link.exitcase newlink.llexitcase = link.llexitcase newlinks.append(newlink) - return newlinks + return v_exitswitch, newlinks def get_specialized_block(self, virtualframe): specblock = self.cache.lookup_spec_block(virtualframe) if specblock is None: orgblock = virtualframe.sourceblock - if orgblock.operations == (): - raise CannotVirtualize("return or except block") + if len(orgblock.exits) == 0: + if virtualframe.callerframe is None: + raise CannotVirtualize("return or except block") + else: + return self.get_specialized_block(virtualframe.callerframe) spec = BlockSpecializer(self) specinputargs = spec.initialize_renamings(virtualframe.copy({})) specblock = Block(specinputargs) @@ -342,11 +346,9 @@ def propagate_specializations(self): while self.pending_specializations: spec, specblock = self.pending_specializations.pop() - sourceblock = spec.virtualframe.sourceblock specblock.operations = spec.specialize_operations() - specblock.exitswitch = spec.rename_nonvirtual( - sourceblock.exitswitch, 'exitswitch') - specblock.closeblock(*self.follow_exits(sourceblock, spec)) + specblock.exitswitch, newlinks = self.follow_exits(spec) + specblock.closeblock(*newlinks) def commit(self): self.startblock.inputargs = self.newinputargs @@ -404,9 +406,16 @@ return [self.renamings[rtnode] for rtnode in rtnodes] def specialize_operations(self): - operations = self.virtualframe.sourceblock.operations newoperations = [] - for op in operations: + # note that 'self.virtualframe' can be changed during the loop! + while True: + operations = self.virtualframe.sourceblock.operations + try: + op = operations[self.virtualframe.nextopindex] + self.virtualframe.nextopindex += 1 + except IndexError: + break + meth = getattr(self, 'handle_op_' + op.opname, self.handle_default) newoperations += meth(op) @@ -468,8 +477,11 @@ assert nb_args == len(graph.getargs()) newnodes = [self.getnode(v) for v in op.args[1:]] if contains_mutable(newnodes): - xxx - return self.handle_default(op) + return self.handle_mutable_call(op, graph, newnodes) + else: + return self.handle_immutable_call(op, graph, newnodes) + + def handle_immutable_call(self, op, graph, newnodes): newgraph = self.mallocspec.get_specialized_graph(graph, newnodes) if newgraph is graph: return self.handle_default(op) @@ -481,6 +493,20 @@ newop = SpaceOperation('direct_call', newargs, newresult) return [newop] + def handle_mutable_call(self, op, graph, newnodes): + sourceblock = self.virtualframe.sourceblock + nextopindex = self.virtualframe.nextopindex + myframe = VirtualFrame(sourceblock, nextopindex, + self.nodes, + self.virtualframe.callerframe) + assert len(graph.getargs()) == len(newnodes) + targetnodes = dict(zip(graph.getargs(), newnodes)) + calleeframe = VirtualFrame(graph.startblock, 0, + targetnodes, myframe) + self.virtualframe = calleeframe + self.nodes = calleeframe.get_nodes_in_use() + return [] + # ____________________________________________________________ # helpers Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Wed Oct 8 19:01:08 2008 @@ -96,7 +96,6 @@ graph = self.check(f, [int], [10], 99) def test_direct_call_mutable_simple(self): - py.test.skip("later") A = lltype.GcStruct('A', ('x', lltype.Signed)) def g(a): a.x += 1 From hpk at codespeak.net Wed Oct 8 19:03:16 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 8 Oct 2008 19:03:16 +0200 (CEST) Subject: [pypy-svn] r58847 - in pypy/build/benchmem: . testing Message-ID: <20081008170316.DA5B616855B@codespeak.net> Author: hpk Date: Wed Oct 8 19:03:16 2008 New Revision: 58847 Modified: pypy/build/benchmem/smaps.py pypy/build/benchmem/testing/test_benchtool.py Log: fix parsing of smap to not confuse which mapping belongs to what Modified: pypy/build/benchmem/smaps.py ============================================================================== --- pypy/build/benchmem/smaps.py (original) +++ pypy/build/benchmem/smaps.py Wed Oct 8 19:03:16 2008 @@ -32,11 +32,12 @@ sizeline = iterlines.next() parts = sizeline.split() if len(parts) != 3: - headline = sizeline + nextheadline = sizeline break value = int(parts[1]) attrs.append(value) append_attrs(attrs) + headline = nextheadline except StopIteration: append_attrs(attrs) self.stream.write(self.SEPSNAPSHOT) Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Wed Oct 8 19:03:16 2008 @@ -99,6 +99,38 @@ l2 = " ".join(lines[2].split()) assert l2 == "32,32,0,0,0,32 402c2000-402c4000 rw-p 402c2000 00:00 0" +def test_log_mapping_two(): + s = py.std.textwrap.dedent("""\ +0035a000-00503000 rw-p 0034a000 1f:04 52612 /root/pypy/dist/pypy-c-optmem +Size: 1700 kB +Rss: 1616 kB +Shared_Clean: 0 kB +Shared_Dirty: 0 kB +Private_Clean: 380 kB +Private_Dirty: 1236 kB +00503000-00545000 rwxp 00503000 00:00 0 [heap] +Size: 264 kB +Rss: 232 kB +Shared_Clean: 0 kB +Shared_Dirty: 0 kB +Private_Clean: 0 kB +Private_Dirty: 232 kB +""") + basedir = py.test.ensuretemp("log_mapping_two") + p = basedir.join("smaps.example") + p.write(s) + + io = py.std.StringIO.StringIO() + rec = smaps.SmapsRecorder(os.getpid(), io) + rec.smapspath = p + rec.snapshot() + result = io.getvalue() + lines = result.split("\n") + l0 = " ".join(lines[0].split()) + l1 = " ".join(lines[1].split()) + assert l0 == "1700,1616,0,0,380,1236 0035a000-00503000 rw-p 0034a000 1f:04 52612 /root/pypy/dist/pypy-c-optmem" + assert l1 == "264,232,0,0,0,232 00503000-00545000 rwxp 00503000 00:00 0 [heap]" + def test_parse_mapping(): line = ("988,796,0,0,796,0 08048000-0813f000 " "r-xp 00000000 fd:00 75457 sometext") From iko at codespeak.net Wed Oct 8 19:28:51 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Wed, 8 Oct 2008 19:28:51 +0200 (CEST) Subject: [pypy-svn] r58848 - in pypy/branch/2.5-merge/pypy/lib: . app_test Message-ID: <20081008172851.E3391169EA7@codespeak.net> Author: iko Date: Wed Oct 8 19:28:49 2008 New Revision: 58848 Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py pypy/branch/2.5-merge/pypy/lib/collections.py Log: (iko, cfbolz) Improve defaultdict repr recursion avoidance fix broken asserts in repr test Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py (original) +++ pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py Wed Oct 8 19:28:49 2008 @@ -61,12 +61,15 @@ d2 = defaultdict(int) assert d2.default_factory == int d2[12] = 42 - assert repr(d2), "defaultdict(, {12: 42})" + assert repr(d2) == "defaultdict(, {12: 42})" def foo(): return 43 d3 = defaultdict(foo) assert d3.default_factory is foo d3[13] - assert repr(d3), "defaultdict(%s, {13: 43})" % repr(foo) + assert repr(d3) == "defaultdict(%s, {13: 43})" % repr(foo) + d4 = defaultdict(int) + d4[14] = defaultdict() + assert repr(d4) == "defaultdict(%s, {14: defaultdict(None, {})})" % repr(int) def test_recursive_repr(self): # Issue2045: stack overflow when default_factory is a bound method Modified: pypy/branch/2.5-merge/pypy/lib/collections.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/collections.py (original) +++ pypy/branch/2.5-merge/pypy/lib/collections.py Wed Oct 8 19:28:49 2008 @@ -337,14 +337,14 @@ self[key] = value = self.default_factory() return value - def __repr__(self, recurse=[]): - if recurse: + def __repr__(self, recurse=set()): + if id(self) in recurse: return "defaultdict(...)" try: - recurse.append(True) + recurse.add(id(self)) return "defaultdict(%s, %s)" % (repr(self.default_factory), super(defaultdict, self).__repr__()) finally: - recurse.pop() + recurse.remove(id(self)) def copy(self): return type(self)(self, default_factory=self.default_factory) From hpk at codespeak.net Wed Oct 8 19:31:10 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 8 Oct 2008 19:31:10 +0200 (CEST) Subject: [pypy-svn] r58849 - pypy/build/benchmem Message-ID: <20081008173110.1AED8169EC5@codespeak.net> Author: hpk Date: Wed Oct 8 19:31:09 2008 New Revision: 58849 Modified: pypy/build/benchmem/report.py pypy/build/benchmem/runbench.py pypy/build/benchmem/smaps.py Log: report private heap for incremental size Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Wed Oct 8 19:31:09 2008 @@ -162,8 +162,8 @@ # checkpoint 0: state before benchmark # checkpoint 1: state at end of benchmark func # checkpoint 2: state after benchmark func finished - basesize = result.snapshots[0].private - inbench = result.snapshots[1].private + basesize = result.snapshots[0].heap_private() + inbench = result.snapshots[1].heap_private() return inbench - basesize class BaseSizeOfInterpreters: Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Wed Oct 8 19:31:09 2008 @@ -182,6 +182,13 @@ self.private = self.private_dirty + self.private_clean self.shared = self.shared_dirty + self.shared_clean + def heap_private(self): + private = 0 + for mapping in self.mappings: + if mapping.filename == "[heap]" or not mapping.filename: + private += mapping.private_clean + mapping.private_dirty + return private + def memusage(self): return "private: %d, shared: %d" %(self.private, self.shared) Modified: pypy/build/benchmem/smaps.py ============================================================================== --- pypy/build/benchmem/smaps.py (original) +++ pypy/build/benchmem/smaps.py Wed Oct 8 19:31:09 2008 @@ -52,6 +52,7 @@ "private_clean private_dirty".split()) # example '402c1000-402c2000 rw-p 00011000 1f:04 1110 /lib/libnsl-2.5.so' _headattrnames = "virtualaddress mode page dev inode filename".split() + filename = '' def __init__(self, line): parts = line.split() From arigo at codespeak.net Wed Oct 8 19:34:49 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 8 Oct 2008 19:34:49 +0200 (CEST) Subject: [pypy-svn] r58850 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081008173449.8F430169E01@codespeak.net> Author: arigo Date: Wed Oct 8 19:34:48 2008 New Revision: 58850 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: (fijal, antocuni, arigo) Return values from inlined called functions -- works. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Wed Oct 8 19:34:48 2008 @@ -301,8 +301,14 @@ # so we can stop specializing. specblock = link.target else: - newframe = VirtualFrame(link.target, 0, targetnodes, - callerframe=currentframe.callerframe) + if len(link.target.exits) == 0: # return or except block + if currentframe.callerframe is None: + raise CannotVirtualize("return or except block") + newframe = self.return_to_caller(currentframe, + link.target, targetnodes) + else: + newframe = VirtualFrame(link.target, 0, targetnodes, + callerframe=currentframe.callerframe) rtnodes = newframe.find_rt_nodes() specblock = self.get_specialized_block(newframe) @@ -313,15 +319,20 @@ newlinks.append(newlink) return v_exitswitch, newlinks + def return_to_caller(self, currentframe, returnblock, targetnodes): + [v_ret] = returnblock.inputargs + retnode = targetnodes[v_ret] + callerframe = currentframe.callerframe + for i in range(len(callerframe.nodelist)): + if isinstance(callerframe.nodelist[i], FutureReturnValue): + callerframe.nodelist[i] = retnode + return callerframe + def get_specialized_block(self, virtualframe): specblock = self.cache.lookup_spec_block(virtualframe) if specblock is None: orgblock = virtualframe.sourceblock - if len(orgblock.exits) == 0: - if virtualframe.callerframe is None: - raise CannotVirtualize("return or except block") - else: - return self.get_specialized_block(virtualframe.callerframe) + assert len(orgblock.exits) != 0 spec = BlockSpecializer(self) specinputargs = spec.initialize_renamings(virtualframe.copy({})) specblock = Block(specinputargs) @@ -496,6 +507,7 @@ def handle_mutable_call(self, op, graph, newnodes): sourceblock = self.virtualframe.sourceblock nextopindex = self.virtualframe.nextopindex + self.nodes[op.result] = FutureReturnValue(op) myframe = VirtualFrame(sourceblock, nextopindex, self.nodes, self.virtualframe.callerframe) @@ -507,11 +519,24 @@ self.nodes = calleeframe.get_nodes_in_use() return [] + +class FutureReturnValue(object): + def __init__(self, op): + self.op = op # for debugging + def getfrozenkey(self, memo): + return None + def accumulate_rt_nodes(self, memo, result): + pass + def copy(self, memo): + return self + # ____________________________________________________________ # helpers def vars_alive_through_op(block, index): # NB. make sure this always returns the variables in the same order + if len(block.exits) == 0: + return block.inputargs # return or except block result = [] seen = {} def see(v): Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Wed Oct 8 19:34:48 2008 @@ -108,6 +108,34 @@ insns = summary(graph) assert insns.get('direct_call', 0) == 0 # no more call, inlined + def test_direct_call_mutable_retval(self): + A = lltype.GcStruct('A', ('x', lltype.Signed)) + def g(a): + a.x += 1 + return a.x * 100 + def f(x): + a = lltype.malloc(A) + a.x = x + y = g(a) + return a.x + y + graph = self.check(f, [int], [41], 4242) + insns = summary(graph) + assert insns.get('direct_call', 0) == 0 # no more call, inlined + + def test_direct_call_mutable_ret_virtual(self): + A = lltype.GcStruct('A', ('x', lltype.Signed)) + def g(a): + a.x += 1 + return a + def f(x): + a = lltype.malloc(A) + a.x = x + b = g(a) + return a.x + b.x + graph = self.check(f, [int], [41], 84) + insns = summary(graph) + assert insns.get('direct_call', 0) == 0 # no more call, inlined + def test_fn2(self): py.test.skip("redo me") class T: From arigo at codespeak.net Fri Oct 10 10:09:13 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 10:09:13 +0200 (CEST) Subject: [pypy-svn] r58867 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081010080913.0BC29169E6F@codespeak.net> Author: arigo Date: Fri Oct 10 10:09:12 2008 New Revision: 58867 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: We don't need to force inlining if we pass the last reference to a mutable object inside the called graph. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Fri Oct 10 10:09:12 2008 @@ -53,8 +53,8 @@ def copy(self, memo): return RuntimeSpecNode(self.name, self.TYPE) - def contains_mutable(self): - return False + def accumulate_mutable_nodes(self, result): + pass class VirtualSpecNode(SpecNode): @@ -89,13 +89,11 @@ newnode.fields.append(subnode.copy(memo)) return newnode - def contains_mutable(self): + def accumulate_mutable_nodes(self, result): if not self.typedesc.immutable_struct: - return True + result.add(self) for subnode in self.fields: - if subnode.contains_mutable(): - return True - return False + subnode.accumulate_mutable_nodes(result) class VirtualFrame(object): @@ -146,6 +144,16 @@ node.accumulate_rt_nodes(memo, result) return result + def share_mutable_nodes_with(self, nodelist): + set1 = set() + for node in nodelist: + node.accumulate_mutable_nodes(set1) + set2 = set() + for frame in self.enum_call_stack(): + for node in frame.nodelist: + node.accumulate_mutable_nodes(set2) + return len(set1 & set2) > 0 + def is_trivial_nodelist(nodelist): for node in nodelist: @@ -153,12 +161,6 @@ return False return True -def contains_mutable(nodelist): - for node in nodelist: - if node.contains_mutable(): - return True - return False - class CannotVirtualize(Exception): pass @@ -487,12 +489,23 @@ nb_args = len(op.args) - 1 assert nb_args == len(graph.getargs()) newnodes = [self.getnode(v) for v in op.args[1:]] - if contains_mutable(newnodes): - return self.handle_mutable_call(op, graph, newnodes) + myframe = self.get_updated_frame(op) + if myframe.share_mutable_nodes_with(newnodes): + return self.handle_inlined_call(myframe, graph, newnodes) else: - return self.handle_immutable_call(op, graph, newnodes) + return self.handle_residual_call(op, graph, newnodes) - def handle_immutable_call(self, op, graph, newnodes): + def get_updated_frame(self, op): + sourceblock = self.virtualframe.sourceblock + nextopindex = self.virtualframe.nextopindex + self.nodes[op.result] = FutureReturnValue(op) + myframe = VirtualFrame(sourceblock, nextopindex, + self.nodes, + self.virtualframe.callerframe) + del self.nodes[op.result] + return myframe + + def handle_residual_call(self, op, graph, newnodes): newgraph = self.mallocspec.get_specialized_graph(graph, newnodes) if newgraph is graph: return self.handle_default(op) @@ -504,13 +517,7 @@ newop = SpaceOperation('direct_call', newargs, newresult) return [newop] - def handle_mutable_call(self, op, graph, newnodes): - sourceblock = self.virtualframe.sourceblock - nextopindex = self.virtualframe.nextopindex - self.nodes[op.result] = FutureReturnValue(op) - myframe = VirtualFrame(sourceblock, nextopindex, - self.nodes, - self.virtualframe.callerframe) + def handle_inlined_call(self, myframe, graph, newnodes): assert len(graph.getargs()) == len(newnodes) targetnodes = dict(zip(graph.getargs(), newnodes)) calleeframe = VirtualFrame(graph.startblock, 0, @@ -529,6 +536,8 @@ pass def copy(self, memo): return self + def accumulate_mutable_nodes(self, result): + pass # ____________________________________________________________ # helpers Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Fri Oct 10 10:09:12 2008 @@ -136,6 +136,20 @@ insns = summary(graph) assert insns.get('direct_call', 0) == 0 # no more call, inlined + def test_direct_call_mutable_lastref(self): + A = lltype.GcStruct('A', ('x', lltype.Signed)) + def g(a): + a.x *= 10 + return a.x + def f(x): + a = lltype.malloc(A) + a.x = x + y = g(a) + return x - y + graph = self.check(f, [int], [5], -45) + insns = summary(graph) + assert insns.get('direct_call', 0) == 1 # not inlined + def test_fn2(self): py.test.skip("redo me") class T: From arigo at codespeak.net Fri Oct 10 10:12:16 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 10:12:16 +0200 (CEST) Subject: [pypy-svn] r58868 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081010081216.13F84169E85@codespeak.net> Author: arigo Date: Fri Oct 10 10:12:14 2008 New Revision: 58868 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Don't use 'immutable' to decide if we can inline; instead, just attempt to not inline, and if we detect a problem (like writing to an object shared by the caller), we cancel the specialized graph and we go for inlining. This required a bit of refactorings all around the place. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Fri Oct 10 10:12:14 2008 @@ -15,7 +15,7 @@ self.names_and_types = [] self.name2index = {} self.initialize_type(MALLOCTYPE) - self.immutable_struct = MALLOCTYPE._hints.get('immutable') + #self.immutable_struct = MALLOCTYPE._hints.get('immutable') def initialize_type(self, TYPE): fieldnames = TYPE._names @@ -47,54 +47,47 @@ def getfrozenkey(self, memo): return 'R' - def accumulate_rt_nodes(self, memo, result): - result.append(self) + def accumulate_nodes(self, rtnodes, vtnodes): + rtnodes.append(self) - def copy(self, memo): + def copy(self, memo, flagreadonly): return RuntimeSpecNode(self.name, self.TYPE) - def accumulate_mutable_nodes(self, result): - pass - class VirtualSpecNode(SpecNode): - def __init__(self, typedesc, fields): + def __init__(self, typedesc, fields, readonly=False): self.typedesc = typedesc self.fields = fields # list of SpecNodes + self.readonly = readonly def getfrozenkey(self, memo): if self in memo: return memo[self] else: memo[self] = len(memo) - result = [self.typedesc] + result = [self.typedesc, self.readonly] for subnode in self.fields: result.append(subnode.getfrozenkey(memo)) return tuple(result) - def accumulate_rt_nodes(self, memo, result): - if self in memo: + def accumulate_nodes(self, rtnodes, vtnodes): + if self in vtnodes: return - memo[self] = True + vtnodes[self] = True for subnode in self.fields: - subnode.accumulate_rt_nodes(memo, result) + subnode.accumulate_nodes(rtnodes, vtnodes) - def copy(self, memo): + def copy(self, memo, flagreadonly): if self in memo: return memo[self] - newnode = VirtualSpecNode(self.typedesc, []) + readonly = self.readonly or self in flagreadonly + newnode = VirtualSpecNode(self.typedesc, [], readonly) memo[self] = newnode for subnode in self.fields: - newnode.fields.append(subnode.copy(memo)) + newnode.fields.append(subnode.copy(memo, flagreadonly)) return newnode - def accumulate_mutable_nodes(self, result): - if not self.typedesc.immutable_struct: - result.add(self) - for subnode in self.fields: - subnode.accumulate_mutable_nodes(result) - class VirtualFrame(object): @@ -108,16 +101,17 @@ def get_nodes_in_use(self): return dict(zip(self.varlist, self.nodelist)) - def copy(self, memo): + def copy(self, memo, flagreadonly={}): newframe = VirtualFrame.__new__(VirtualFrame) newframe.varlist = self.varlist - newframe.nodelist = [node.copy(memo) for node in self.nodelist] + newframe.nodelist = [node.copy(memo, flagreadonly) + for node in self.nodelist] newframe.sourceblock = self.sourceblock newframe.nextopindex = self.nextopindex if self.callerframe is None: newframe.callerframe = None else: - newframe.callerframe = self.callerframe.copy(memo) + newframe.callerframe = self.callerframe.copy(memo, flagreadonly) return newframe def enum_call_stack(self): @@ -136,24 +130,42 @@ key.append(node.getfrozenkey(memo)) return tuple(key) - def find_rt_nodes(self): - result = [] - memo = {} + def find_all_nodes(self): + rtnodes = [] + vtnodes = {} for frame in self.enum_call_stack(): for node in frame.nodelist: - node.accumulate_rt_nodes(memo, result) - return result + node.accumulate_nodes(rtnodes, vtnodes) + return rtnodes, vtnodes - def share_mutable_nodes_with(self, nodelist): - set1 = set() - for node in nodelist: - node.accumulate_mutable_nodes(set1) - set2 = set() - for frame in self.enum_call_stack(): - for node in frame.nodelist: - node.accumulate_mutable_nodes(set2) - return len(set1 & set2) > 0 + def find_rt_nodes(self): + rtnodes, vtnodes = self.find_all_nodes() + return rtnodes + def find_vt_nodes(self): + rtnodes, vtnodes = self.find_all_nodes() + return vtnodes + + def return_to_caller(self, returnblock, targetnodes): + [v_ret] = returnblock.inputargs + retnode = targetnodes[v_ret] + callerframe = self.callerframe + for i in range(len(callerframe.nodelist)): + if isinstance(callerframe.nodelist[i], FutureReturnValue): + callerframe.nodelist[i] = retnode + return callerframe + + +def copynodes(nodelist, flagreadonly={}): + memo = {} + return [node.copy(memo, flagreadonly) for node in nodelist] + +def find_all_nodes(nodelist): + rtnodes = [] + vtnodes = {} + for node in nodelist: + node.accumulate_nodes(rtnodes, vtnodes) + return rtnodes, vtnodes def is_trivial_nodelist(nodelist): for node in nodelist: @@ -165,15 +177,19 @@ class CannotVirtualize(Exception): pass +class ForcedInline(Exception): + pass + class MallocVirtualizer(object): - def __init__(self, graphs): + def __init__(self, graphs, verbose=False): self.graphs = graphs - self.new_graphs = {} - self.cache = BlockSpecCache() + self.graphbuilders = {} + self.specialized_graphs = FrameKeyCache() self.malloctypedescs = {} self.count_virtualized = 0 + self.verbose = verbose def report_result(self): log.mallocv('removed %d mallocs so far' % (self.count_virtualized,)) @@ -187,209 +203,172 @@ result.append((block, op)) return result - def remove_mallocs_once(self, verbose=False): + def remove_mallocs_once(self): prev = self.count_virtualized for graph in self.graphs: + all_blocks = None all_mallocs = self.find_all_mallocs(graph) for block, op in all_mallocs: + if all_blocks is None: + all_blocks = set(graph.iterblocks()) + if block not in all_blocks: + continue # this block was removed from the graph + # by a previous try_remove_malloc() try: - self.try_remove_malloc(block, op) - if verbose: - log.mallocv('%s removed' % (op.result,)) - break # don't continue on this graph, which was mutated + self.try_remove_malloc(graph, block, op) except CannotVirtualize, e: - if verbose: + if self.verbose: log.mallocv('%s failed: %s' % (op.result, e)) - self.put_new_graphs_back_in_translator() + else: + if self.verbose: + log.mallocv('%s removed' % (op.result,)) + all_blocks = None progress = self.report_result() - prev return progress - def try_remove_malloc(self, block, op): - MALLOCTYPE = op.result.concretetype.TO + def getmalloctypedesc(self, MALLOCTYPE): try: dsc = self.malloctypedescs[MALLOCTYPE] except KeyError: dsc = self.malloctypedescs[MALLOCTYPE] = MallocTypeDesc(MALLOCTYPE) - mallocspec = MallocSpecializer(self, dsc) - mallocspec.remove_malloc(block, op.result) - mallocspec.propagate_specializations() - # if we read this point without a CannotVirtualize, success - mallocspec.commit() + return dsc + + def try_remove_malloc(self, graph, block, op): + graphbuilder = GraphBuilder(self) + if graph in self.graphbuilders: + graphbuilder.initialize_from_old_builder(self.graphbuilders[graph]) + graphbuilder.start_from_a_malloc(block, op.result) + graphbuilder.propagate_specializations() + # if we reach this point without a CannotVirtualize, success + graphbuilder.finished_removing_malloc() + self.graphbuilders[graph] = graphbuilder self.count_virtualized += 1 - def put_new_graphs_back_in_translator(self): - for graph in self.cache.graph_starting_at.values(): - if graph not in self.new_graphs: - self.new_graphs[graph] = True - self.graphs.append(graph) + def get_specialized_graph(self, graph, nodelist): + assert len(graph.getargs()) == len(nodelist) + if is_trivial_nodelist(nodelist): + return 'trivial', graph + nodes = dict(zip(graph.getargs(), nodelist)) + virtualframe = VirtualFrame(graph.startblock, 0, nodes) + try: + return self.specialized_graphs.getitem(virtualframe) + except KeyError: + self.build_specialized_graph(graph, virtualframe) + return self.specialized_graphs.getitem(virtualframe) + def build_specialized_graph(self, graph, virtualframe): + graphbuilder = GraphBuilder(self) + specblock = graphbuilder.start_from_virtualframe(virtualframe) + specgraph = FunctionGraph(graph.name + '_mallocv', specblock) + self.specialized_graphs.setitem(virtualframe, ('call', specgraph)) + try: + graphbuilder.propagate_specializations() + except ForcedInline, e: + if self.verbose: + log.mallocv('%s inlined: %s' % (graph.name, e)) + self.specialized_graphs.setitem(virtualframe, ('inline', None)) + except CannotVirtualize, e: + if self.verbose: + log.mallocv('%s failing: %s' % (graph.name, e)) + self.specialized_graphs.setitem(virtualframe, ('fail', None)) + else: + self.graphbuilders[specgraph] = graphbuilder + self.graphs.append(specgraph) -class BlockSpecCache(object): - def __init__(self, fallback=None): - self.specialized_blocks = {} # {frame_frozen_key: spec Block} - self.graph_starting_at = {} # {spec Block: spec Graph} - self.fallback = fallback +class FrameKeyCache(object): - def lookup_spec_block(self, virtualframe): - key = virtualframe.getfrozenkey() - try: - return self.specialized_blocks[key] - except KeyError: - if self.fallback is None: - return None - else: - return self.fallback.specialized_blocks.get(key) + def __init__(self): + self.content = {} - def remember_spec_block(self, virtualframe, specblock): + def get(self, virtualframe): key = virtualframe.getfrozenkey() - self.specialized_blocks[key] = specblock + return self.content.get(key) - def lookup_graph_starting_at(self, startblock): - try: - return self.graph_starting_at[startblock] - except KeyError: - if self.fallback is None: - return None - else: - return self.fallback.graph_starting_at.get(startblock) + def getitem(self, virtualframe): + key = virtualframe.getfrozenkey() + return self.content[key] - def remember_graph_starting_at(self, startblock, graph): - self.graph_starting_at[startblock] = graph + def setitem(self, virtualframe, value): + key = virtualframe.getfrozenkey() + self.content[key] = value - def push_changes(self): - self.fallback.specialized_blocks.update(self.specialized_blocks) - self.fallback.graph_starting_at.update(self.graph_starting_at) + def update(self, other): + self.content.update(other.content) -class MallocSpecializer(object): +class GraphBuilder(object): - def __init__(self, mallocv, malloctypedesc): + def __init__(self, mallocv): self.mallocv = mallocv - self.malloctypedesc = malloctypedesc + self.specialized_blocks = FrameKeyCache() self.pending_specializations = [] - self.cache = BlockSpecCache(fallback=mallocv.cache) - def remove_malloc(self, block, v_result): - self.startblock = block - spec = BlockSpecializer(self, v_result) + def initialize_from_old_builder(self, oldbuilder): + self.specialized_blocks.update(oldbuilder.specialized_blocks) + + def start_from_virtualframe(self, startframe): + spec = BlockSpecializer(self) + spec.initialize_renamings(startframe) + self.pending_specializations.append(spec) + return spec.specblock + + def start_from_a_malloc(self, block, v_result): nodes = {} for v in block.inputargs: nodes[v] = RuntimeSpecNode(v, v.concretetype) trivialframe = VirtualFrame(block, 0, nodes) - self.newinputargs = spec.initialize_renamings(trivialframe) - self.newoperations = spec.specialize_operations() - self.newexitswitch, self.newexits = self.follow_exits(spec) - - def follow_exits(self, spec): - currentframe = spec.virtualframe - block = currentframe.sourceblock - v_exitswitch = spec.rename_nonvirtual(block.exitswitch, - 'exitswitch') - newlinks = [] - for link in block.exits: - targetnodes = {} - - rtnodes = [] - for v1, v2 in zip(link.args, link.target.inputargs): - node = spec.getnode(v1) - if isinstance(node, RuntimeSpecNode): - rtnodes.append(node) - targetnodes[v2] = node - - if (len(rtnodes) == len(link.args) and - currentframe.callerframe is None): - # there is no more VirtualSpecNodes being passed around, - # so we can stop specializing. - specblock = link.target - else: - if len(link.target.exits) == 0: # return or except block - if currentframe.callerframe is None: - raise CannotVirtualize("return or except block") - newframe = self.return_to_caller(currentframe, - link.target, targetnodes) - else: - newframe = VirtualFrame(link.target, 0, targetnodes, - callerframe=currentframe.callerframe) - rtnodes = newframe.find_rt_nodes() - specblock = self.get_specialized_block(newframe) - - linkargs = [spec.renamings[rtnode] for rtnode in rtnodes] - newlink = Link(linkargs, specblock) - newlink.exitcase = link.exitcase - newlink.llexitcase = link.llexitcase - newlinks.append(newlink) - return v_exitswitch, newlinks - - def return_to_caller(self, currentframe, returnblock, targetnodes): - [v_ret] = returnblock.inputargs - retnode = targetnodes[v_ret] - callerframe = currentframe.callerframe - for i in range(len(callerframe.nodelist)): - if isinstance(callerframe.nodelist[i], FutureReturnValue): - callerframe.nodelist[i] = retnode - return callerframe + spec = BlockSpecializer(self, v_result) + spec.initialize_renamings(trivialframe) + self.pending_specializations.append(spec) + self.pending_patch = (block, spec.specblock) + + def finished_removing_malloc(self): + (srcblock, specblock) = self.pending_patch + srcblock.inputargs = specblock.inputargs + srcblock.operations = specblock.operations + srcblock.exitswitch = specblock.exitswitch + srcblock.recloseblock(*specblock.exits) def get_specialized_block(self, virtualframe): - specblock = self.cache.lookup_spec_block(virtualframe) + specblock = self.specialized_blocks.get(virtualframe) if specblock is None: orgblock = virtualframe.sourceblock assert len(orgblock.exits) != 0 spec = BlockSpecializer(self) - specinputargs = spec.initialize_renamings(virtualframe.copy({})) - specblock = Block(specinputargs) - self.pending_specializations.append((spec, specblock)) - self.cache.remember_spec_block(virtualframe, specblock) + spec.initialize_renamings(virtualframe) + self.pending_specializations.append(spec) + specblock = spec.specblock + self.specialized_blocks.setitem(virtualframe, specblock) return specblock - def get_specialized_graph(self, graph, nodelist): - if is_trivial_nodelist(nodelist): - return graph - block = graph.startblock - assert len(graph.getargs()) == len(nodelist) - nodes = dict(zip(graph.getargs(), nodelist)) - virtualframe = VirtualFrame(block, 0, nodes) - specblock = self.get_specialized_block(virtualframe) - specgraph = self.cache.lookup_graph_starting_at(specblock) - if specgraph is None: - specgraph = FunctionGraph(graph.name + '_mallocv', specblock) - self.cache.remember_graph_starting_at(specblock, specgraph) - return specgraph - def propagate_specializations(self): while self.pending_specializations: - spec, specblock = self.pending_specializations.pop() - specblock.operations = spec.specialize_operations() - specblock.exitswitch, newlinks = self.follow_exits(spec) - specblock.closeblock(*newlinks) - - def commit(self): - self.startblock.inputargs = self.newinputargs - self.startblock.operations = self.newoperations - self.startblock.exitswitch = self.newexitswitch - self.startblock.recloseblock(*self.newexits) - self.cache.push_changes() + spec = self.pending_specializations.pop() + spec.specialize_operations() + spec.follow_exits() class BlockSpecializer(object): - def __init__(self, mallocspec, v_expand_malloc=None): - self.mallocspec = mallocspec + def __init__(self, graphbuilder, v_expand_malloc=None): + self.graphbuilder = graphbuilder self.v_expand_malloc = v_expand_malloc + self.specblock = Block([]) def initialize_renamings(self, virtualframe): - # the caller is responsible for making a copy of 'virtualframe' - # if needed, because the BlockSpecializer will mutate some of its - # content. + # we make a copy of the original 'virtualframe' because the + # specialize_operations() will mutate some of its content. + virtualframe = virtualframe.copy({}) self.virtualframe = virtualframe self.nodes = virtualframe.get_nodes_in_use() self.renamings = {} # {RuntimeSpecNode(): Variable()} - result = [] + specinputargs = [] for rtnode in virtualframe.find_rt_nodes(): v = rtnode.newvar() self.renamings[rtnode] = v - result.append(v) - return result + specinputargs.append(v) + self.specblock.inputargs = specinputargs def setnode(self, v, node): assert v not in self.nodes @@ -412,10 +391,7 @@ return self.renamings[node] def expand_nodes(self, nodelist): - memo = {} - rtnodes = [] - for node in nodelist: - node.accumulate_rt_nodes(memo, rtnodes) + rtnodes, vtnodes = find_all_nodes(nodelist) return [self.renamings[rtnode] for rtnode in rtnodes] def specialize_operations(self): @@ -432,7 +408,47 @@ meth = getattr(self, 'handle_op_' + op.opname, self.handle_default) newoperations += meth(op) - return newoperations + self.specblock.operations = newoperations + + def follow_exits(self): + currentframe = self.virtualframe + block = currentframe.sourceblock + self.specblock.exitswitch = self.rename_nonvirtual(block.exitswitch, + 'exitswitch') + newlinks = [] + for link in block.exits: + targetnodes = {} + + rtnodes = [] + for v1, v2 in zip(link.args, link.target.inputargs): + node = self.getnode(v1) + if isinstance(node, RuntimeSpecNode): + rtnodes.append(node) + targetnodes[v2] = node + + if (len(rtnodes) == len(link.args) and + currentframe.callerframe is None): + # there is no more VirtualSpecNodes being passed around, + # so we can stop specializing. + specblock = link.target + else: + if len(link.target.exits) == 0: # return or except block + if currentframe.callerframe is None: + raise CannotVirtualize("return or except block") + newframe = currentframe.return_to_caller(link.target, + targetnodes) + else: + newframe = VirtualFrame(link.target, 0, targetnodes, + callerframe=currentframe.callerframe) + rtnodes = newframe.find_rt_nodes() + specblock = self.graphbuilder.get_specialized_block(newframe) + + linkargs = [self.renamings[rtnode] for rtnode in rtnodes] + newlink = Link(linkargs, specblock) + newlink.exitcase = link.exitcase + newlink.llexitcase = link.llexitcase + newlinks.append(newlink) + self.specblock.closeblock(*newlinks) def make_rt_result(self, v_result): newrtnode = RuntimeSpecNode(v_result, v_result.concretetype) @@ -459,6 +475,8 @@ def handle_op_setfield(self, op): node = self.getnode(op.args[0]) if isinstance(node, VirtualSpecNode): + if node.readonly: + raise ForcedInline(op) fieldname = op.args[1].value index = node.typedesc.name2index[fieldname] node.fields[index] = self.getnode(op.args[2]) @@ -468,7 +486,8 @@ def handle_op_malloc(self, op): if op.result is self.v_expand_malloc: - typedesc = self.mallocspec.malloctypedesc + MALLOCTYPE = op.result.concretetype.TO + typedesc = self.graphbuilder.mallocv.getmalloctypedesc(MALLOCTYPE) virtualnode = VirtualSpecNode(typedesc, []) self.setnode(op.result, virtualnode) for name, FIELDTYPE in typedesc.names_and_types: @@ -490,10 +509,19 @@ assert nb_args == len(graph.getargs()) newnodes = [self.getnode(v) for v in op.args[1:]] myframe = self.get_updated_frame(op) - if myframe.share_mutable_nodes_with(newnodes): + argnodes = copynodes(newnodes, flagreadonly=myframe.find_vt_nodes()) + mallocv = self.graphbuilder.mallocv + kind, newgraph = mallocv.get_specialized_graph(graph, argnodes) + if kind == 'trivial': + return self.handle_default(op) + elif kind == 'inline': return self.handle_inlined_call(myframe, graph, newnodes) + elif kind == 'call': + return self.handle_residual_call(op, newgraph, newnodes) + elif kind == 'fail': + raise CannotVirtualize(op) else: - return self.handle_residual_call(op, graph, newnodes) + raise ValueError(kind) def get_updated_frame(self, op): sourceblock = self.virtualframe.sourceblock @@ -505,10 +533,7 @@ del self.nodes[op.result] return myframe - def handle_residual_call(self, op, graph, newnodes): - newgraph = self.mallocspec.get_specialized_graph(graph, newnodes) - if newgraph is graph: - return self.handle_default(op) + def handle_residual_call(self, op, newgraph, newnodes): fspecptr = getfunctionptr(newgraph) newargs = [Constant(fspecptr, concretetype=lltype.typeOf(fspecptr))] @@ -532,12 +557,10 @@ self.op = op # for debugging def getfrozenkey(self, memo): return None - def accumulate_rt_nodes(self, memo, result): + def accumulate_nodes(self, rtnodes, vtnodes): pass - def copy(self, memo): + def copy(self, memo, flagreadonly): return self - def accumulate_mutable_nodes(self, result): - pass # ____________________________________________________________ # helpers Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Fri Oct 10 10:12:14 2008 @@ -44,9 +44,9 @@ # to detect missing keepalives and broken intermediate graphs, # we do the loop ourselves instead of calling remove_simple_mallocs() maxiter = 100 - mallocv = MallocVirtualizer(t.graphs) + mallocv = MallocVirtualizer(t.graphs, verbose=True) while True: - progress = mallocv.remove_mallocs_once(verbose=True) + progress = mallocv.remove_mallocs_once() #simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks())) if progress and option.view: t.view() From arigo at codespeak.net Fri Oct 10 10:13:02 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 10:13:02 +0200 (CEST) Subject: [pypy-svn] r58869 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081010081302.A403D169E85@codespeak.net> Author: arigo Date: Fri Oct 10 10:13:01 2008 New Revision: 58869 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Returning a virtual should force inlining, not cancel the whole malloc removal attempt. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Fri Oct 10 10:13:01 2008 @@ -204,6 +204,7 @@ return result def remove_mallocs_once(self): + self.flush_failed_specializations() prev = self.count_virtualized for graph in self.graphs: all_blocks = None @@ -214,18 +215,17 @@ if block not in all_blocks: continue # this block was removed from the graph # by a previous try_remove_malloc() - try: - self.try_remove_malloc(graph, block, op) - except CannotVirtualize, e: - if self.verbose: - log.mallocv('%s failed: %s' % (op.result, e)) - else: - if self.verbose: - log.mallocv('%s removed' % (op.result,)) - all_blocks = None + if self.try_remove_malloc(graph, block, op): + all_blocks = None # graph mutated progress = self.report_result() - prev return progress + def flush_failed_specializations(self): + cache = self.specialized_graphs.content + for key, (mode, specgraph) in cache.items(): + if mode == 'fail': + del cache[key] + def getmalloctypedesc(self, MALLOCTYPE): try: dsc = self.malloctypedescs[MALLOCTYPE] @@ -238,11 +238,19 @@ if graph in self.graphbuilders: graphbuilder.initialize_from_old_builder(self.graphbuilders[graph]) graphbuilder.start_from_a_malloc(block, op.result) - graphbuilder.propagate_specializations() - # if we reach this point without a CannotVirtualize, success - graphbuilder.finished_removing_malloc() - self.graphbuilders[graph] = graphbuilder - self.count_virtualized += 1 + try: + graphbuilder.propagate_specializations() + except (CannotVirtualize, ForcedInline), e: + if self.verbose: + log.mallocv('%s %s: %s' % (op.result, e.__class__.__name__, e)) + return False + else: + if self.verbose: + log.mallocv('%s removed' % (op.result,)) + graphbuilder.finished_removing_malloc() + self.graphbuilders[graph] = graphbuilder + self.count_virtualized += 1 + return True def get_specialized_graph(self, graph, nodelist): assert len(graph.getargs()) == len(nodelist) @@ -434,7 +442,7 @@ else: if len(link.target.exits) == 0: # return or except block if currentframe.callerframe is None: - raise CannotVirtualize("return or except block") + raise ForcedInline("return or except block") newframe = currentframe.return_to_caller(link.target, targetnodes) else: Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Fri Oct 10 10:13:01 2008 @@ -150,6 +150,22 @@ insns = summary(graph) assert insns.get('direct_call', 0) == 1 # not inlined + def test_direct_call_ret_virtual(self): + A = lltype.GcStruct('A', ('x', lltype.Signed)) + prebuilt_a = lltype.malloc(A) + def g(a): + prebuilt_a.x += a.x + return a + def f(n): + prebuilt_a.x = n + a = lltype.malloc(A) + a.x = 2 + a = g(a) + return prebuilt_a.x * a.x + graph = self.check(f, [int], [19], 42) + insns = summary(graph) + assert insns.get('direct_call', 0) == 0 # inlined + def test_fn2(self): py.test.skip("redo me") class T: From arigo at codespeak.net Fri Oct 10 10:13:31 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 10:13:31 +0200 (CEST) Subject: [pypy-svn] r58870 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081010081331.DF5CD169E4E@codespeak.net> Author: arigo Date: Fri Oct 10 10:13:31 2008 New Revision: 58870 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Add a checkgraphs() in the test. Corresponding fix in the code. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Fri Oct 10 10:13:31 2008 @@ -1,5 +1,5 @@ from pypy.objspace.flow.model import Variable, Constant, Block, Link -from pypy.objspace.flow.model import SpaceOperation, FunctionGraph +from pypy.objspace.flow.model import SpaceOperation, FunctionGraph, copygraph from pypy.translator.backendopt.support import log from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import lltype @@ -261,24 +261,30 @@ try: return self.specialized_graphs.getitem(virtualframe) except KeyError: - self.build_specialized_graph(graph, virtualframe) + self.build_specialized_graph(graph, virtualframe, nodelist) return self.specialized_graphs.getitem(virtualframe) - def build_specialized_graph(self, graph, virtualframe): + def build_specialized_graph(self, graph, key, nodelist): + graph2 = copygraph(graph) + nodes = dict(zip(graph2.getargs(), nodelist)) + virtualframe = VirtualFrame(graph2.startblock, 0, nodes) graphbuilder = GraphBuilder(self) specblock = graphbuilder.start_from_virtualframe(virtualframe) - specgraph = FunctionGraph(graph.name + '_mallocv', specblock) - self.specialized_graphs.setitem(virtualframe, ('call', specgraph)) + specblock.isstartblock = True + specgraph = graph2 + specgraph.name += '_mallocv' + specgraph.startblock = specblock + self.specialized_graphs.setitem(key, ('call', specgraph)) try: graphbuilder.propagate_specializations() except ForcedInline, e: if self.verbose: log.mallocv('%s inlined: %s' % (graph.name, e)) - self.specialized_graphs.setitem(virtualframe, ('inline', None)) + self.specialized_graphs.setitem(key, ('inline', None)) except CannotVirtualize, e: if self.verbose: log.mallocv('%s failing: %s' % (graph.name, e)) - self.specialized_graphs.setitem(virtualframe, ('fail', None)) + self.specialized_graphs.setitem(key, ('fail', None)) else: self.graphbuilders[specgraph] = graphbuilder self.graphs.append(specgraph) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Fri Oct 10 10:13:31 2008 @@ -50,6 +50,7 @@ #simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks())) if progress and option.view: t.view() + t.checkgraphs() if expected_result is not Ellipsis: interp = LLInterpreter(t.rtyper) res = interp.eval_graph(graph, args) From arigo at codespeak.net Fri Oct 10 10:14:11 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 10:14:11 +0200 (CEST) Subject: [pypy-svn] r58871 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081010081411.BC31E169E4E@codespeak.net> Author: arigo Date: Fri Oct 10 10:14:11 2008 New Revision: 58871 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_malloc.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: A test that fails in the old "malloc.py". Make it pass in the new "mallocv.py". Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Fri Oct 10 10:14:11 2008 @@ -476,6 +476,14 @@ newresult = self.make_rt_result(op.result) return [SpaceOperation(op.opname, newargs, newresult)] + def handle_unreachable(self, op): + from pypy.rpython.lltypesystem.rstr import string_repr + msg = 'unreachable: %s' % (op,) + ll_msg = string_repr.convert_const(msg) + c_msg = Constant(ll_msg, lltype.typeOf(ll_msg)) + newresult = self.make_rt_result(op.result) + return [SpaceOperation('debug_fatalerror', [c_msg], newresult)] + def handle_op_getfield(self, op): node = self.getnode(op.args[0]) if isinstance(node, VirtualSpecNode): @@ -498,6 +506,31 @@ else: return self.handle_default(op) + def handle_op_same_as(self, op): + node = self.getnode(op.args[0]) + if isinstance(node, VirtualSpecNode): + node = self.getnode(op.args[0]) + self.setnode(op.result, node) + return [] + else: + return self.handle_default(op) + + def handle_op_cast_pointer(self, op): + node = self.getnode(op.args[0]) + if isinstance(node, VirtualSpecNode): + node = self.getnode(op.args[0]) + SOURCEPTR = lltype.Ptr(node.typedesc.MALLOCTYPE) + TARGETPTR = op.result.concretetype + try: + if lltype.castable(TARGETPTR, SOURCEPTR) < 0: + raise lltype.InvalidCast + except lltype.InvalidCast: + return self.handle_unreachable(op) + self.setnode(op.result, node) + return [] + else: + return self.handle_default(op) + def handle_op_malloc(self, op): if op.result is self.v_expand_malloc: MALLOCTYPE = op.result.concretetype.TO Modified: pypy/dist/pypy/translator/backendopt/test/test_malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_malloc.py Fri Oct 10 10:14:11 2008 @@ -383,6 +383,19 @@ return u[0].s.x graph = self.check(f, [int], [42], 42) + def test_bogus_cast_pointer(self): + py.test.skip("XXX fix me") + S = lltype.GcStruct("S", ('x', lltype.Signed)) + T = lltype.GcStruct("T", ('s', S), ('y', lltype.Signed)) + def f(x): + s = lltype.malloc(S) + s.x = 123 + if x < 0: + t = lltype.cast_pointer(lltype.Ptr(T), s) + t.y += 1 + return s.x + graph = self.check(f, [int], [5], 123) + class TestOOTypeMallocRemoval(BaseMallocRemovalTest): type_system = 'ootype' Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Fri Oct 10 10:14:11 2008 @@ -43,7 +43,6 @@ t.view() # to detect missing keepalives and broken intermediate graphs, # we do the loop ourselves instead of calling remove_simple_mallocs() - maxiter = 100 mallocv = MallocVirtualizer(t.graphs, verbose=True) while True: progress = mallocv.remove_mallocs_once() @@ -168,7 +167,6 @@ assert insns.get('direct_call', 0) == 0 # inlined def test_fn2(self): - py.test.skip("redo me") class T: pass def fn2(x, y): @@ -502,6 +500,18 @@ return u[0].s.x graph = self.check(f, [int], [42], 42) + def test_bogus_cast_pointer(self): + S = lltype.GcStruct("S", ('x', lltype.Signed)) + T = lltype.GcStruct("T", ('s', S), ('y', lltype.Signed)) + def f(x): + s = lltype.malloc(S) + s.x = 123 + if x < 0: + t = lltype.cast_pointer(lltype.Ptr(T), s) + t.y += 1 + return s.x + graph = self.check(f, [int], [5], 123) + class DISABLED_TestOOTypeMallocRemoval(BaseMallocRemovalTest): type_system = 'ootype' From arigo at codespeak.net Fri Oct 10 10:14:28 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 10:14:28 +0200 (CEST) Subject: [pypy-svn] r58872 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081010081428.1CECD169E4E@codespeak.net> Author: arigo Date: Fri Oct 10 10:14:27 2008 New Revision: 58872 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: More tests pass. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Fri Oct 10 10:14:27 2008 @@ -531,6 +531,13 @@ else: return self.handle_default(op) + def handle_op_keepalive(self, op): + node = self.getnode(op.args[0]) + if isinstance(node, VirtualSpecNode): + return [] + else: + return self.handle_default(op) + def handle_op_malloc(self, op): if op.result is self.v_expand_malloc: MALLOCTYPE = op.result.concretetype.TO Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Fri Oct 10 10:14:27 2008 @@ -180,14 +180,12 @@ self.check(fn2, [int, int], [-6, 7], -13) def test_fn3(self): - py.test.skip("redo me") def fn3(x): a, ((b, c), d, e) = x+1, ((x+2, x+3), x+4, x+5) return a+b+c+d+e self.check(fn3, [int], [10], 65) def test_fn4(self): - py.test.skip("redo me") class A: pass class B(A): @@ -201,7 +199,6 @@ self.check(fn4, [int], [42], 42) def test_fn5(self): - py.test.skip("redo me") class A: attr = 666 class B(A): @@ -212,7 +209,6 @@ self.check(fn5, [], [], 42) def test_aliasing(self): - py.test.skip("redo me") class A: pass def fn6(n): @@ -226,7 +222,7 @@ a = a2 a.x = 12 return a1.x - self.check(fn6, [int], [1], 12, must_be_removed=False) + self.check(fn6, [int], [1], 12) @@ -235,7 +231,6 @@ #MallocRemover = LLTypeMallocRemover def test_with_keepalive(self): - py.test.skip("redo me") from pypy.rlib.objectmodel import keepalive_until_here def fn1(x, y): if x > 0: From xoraxax at codespeak.net Fri Oct 10 10:17:03 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 10 Oct 2008 10:17:03 +0200 (CEST) Subject: [pypy-svn] r58873 - in pypy/dist/pypy/translator: . tool Message-ID: <20081010081703.73C26169E85@codespeak.net> Author: xoraxax Date: Fri Oct 10 10:17:02 2008 New Revision: 58873 Modified: pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/tool/staticsizereport.py Log: Copy the staticsizeinfo also to goal, clean up driver a bit. Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Fri Oct 10 10:17:02 2008 @@ -1,4 +1,6 @@ import sys, os +import os.path +import shutil from pypy.translator.translator import TranslationContext, graphof from pypy.translator.tool.taskengine import SimpleTaskEngine @@ -494,20 +496,22 @@ if self.config.translation.dump_static_data_info: from pypy.translator.tool.staticsizereport import dump_static_data_info targetdir = cbuilder.targetdir - dump_static_data_info(self.log, database, targetdir) + fname = dump_static_data_info(self.log, database, targetdir) + shutil.copy(str(fname), self.compute_exe_name() + '.staticdata.info') # task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source") + def compute_exe_name(self): + newexename = self.exe_name % self.get_info() + if '/' not in newexename and '\\' not in newexename: + newexename = './' + newexename + return mkexename(newexename) + def create_exe(self): if self.exe_name is not None: - import shutil exename = mkexename(self.c_entryp) - info = {'backend': self.config.translation.backend} - newexename = self.exe_name % self.get_info() - if '/' not in newexename and '\\' not in newexename: - newexename = './' + newexename - newexename = mkexename(newexename) + newexename = self.compute_exe_name() shutil.copy(exename, newexename) self.c_entryp = newexename self.log.info("created: %s" % (self.c_entryp,)) @@ -650,8 +654,6 @@ def copy_cli_exe(self): # XXX messy - import os.path - import shutil main_exe = self.c_entryp._exe usession_path, main_exe_name = os.path.split(main_exe) pypylib_dll = os.path.join(usession_path, 'pypylib.dll') @@ -683,8 +685,6 @@ os.chmod(newexename, 0755) def copy_cli_dll(self): - import os.path - import shutil dllname = self.gen.outfile usession_path, dll_name = os.path.split(dllname) pypylib_dll = os.path.join(usession_path, 'pypylib.dll') Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Fri Oct 10 10:17:02 2008 @@ -176,6 +176,7 @@ pickle.dump(info, f) f.close() log.info('static data informations dumped to %s' % infofile) + return infofile ## Functions used by the reportstaticdata.py script From arigo at codespeak.net Fri Oct 10 10:31:08 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 10:31:08 +0200 (CEST) Subject: [pypy-svn] r58875 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081010083108.8B31E169E1B@codespeak.net> Author: arigo Date: Fri Oct 10 10:31:07 2008 New Revision: 58875 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: (fijal, arigo) * Don't malloc-remove structures with a destructor. * Improve the tests, counting remaining mallocs and remaining calls. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Fri Oct 10 10:31:07 2008 @@ -11,11 +11,24 @@ class MallocTypeDesc(object): def __init__(self, MALLOCTYPE): + if not isinstance(MALLOCTYPE, lltype.GcStruct): + raise CannotRemoveThisType self.MALLOCTYPE = MALLOCTYPE self.names_and_types = [] self.name2index = {} self.initialize_type(MALLOCTYPE) #self.immutable_struct = MALLOCTYPE._hints.get('immutable') + self.check_no_destructor() + + def check_no_destructor(self): + STRUCT = self.MALLOCTYPE + try: + rttiptr = lltype.getRuntimeTypeInfo(STRUCT) + except ValueError: + return # ok + destr_ptr = getattr(rttiptr._obj, 'destructor_funcptr', None) + if destr_ptr: + raise CannotRemoveThisType def initialize_type(self, TYPE): fieldnames = TYPE._names @@ -180,6 +193,9 @@ class ForcedInline(Exception): pass +class CannotRemoveThisType(Exception): + pass + class MallocVirtualizer(object): @@ -200,7 +216,13 @@ for block in graph.iterblocks(): for op in block.operations: if op.opname == 'malloc': - result.append((block, op)) + MALLOCTYPE = op.result.concretetype.TO + try: + self.getmalloctypedesc(MALLOCTYPE) + except CannotRemoveThisType: + pass + else: + result.append((block, op)) return result def remove_mallocs_once(self): Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Fri Oct 10 10:31:07 2008 @@ -20,21 +20,22 @@ if self.type_system == 'ootype': py.test.skip(msg) - def check_malloc_removed(cls, graph): - #remover = cls.MallocRemover() - checkgraph(graph) - count = 0 + def check_malloc_removed(cls, graph, expected_mallocs, expected_calls): + count_mallocs = 0 + count_calls = 0 for node in flatten(graph): if isinstance(node, Block): for op in node.operations: - if op.opname == 'malloc': #cls.MallocRemover.MALLOC_OP: - S = op.args[0].value - #if not remover.union_wrapper(S): # union wrappers are fine - count += 1 - assert count == 0 # number of mallocs left + if op.opname == 'malloc': + count_mallocs += 1 + if op.opname == 'direct_call': + count_calls += 1 + assert count_mallocs == expected_mallocs + assert count_calls == expected_calls check_malloc_removed = classmethod(check_malloc_removed) - def check(self, fn, signature, args, expected_result, must_be_removed=True): + def check(self, fn, signature, args, expected_result, + expected_mallocs=0, expected_calls=0): t = TranslationContext() t.buildannotator().build_types(fn, signature) t.buildrtyper(type_system=self.type_system).specialize() @@ -56,8 +57,7 @@ assert res == expected_result if not progress: break - if must_be_removed: - self.check_malloc_removed(graph) + self.check_malloc_removed(graph, expected_mallocs, expected_calls) return graph def test_fn1(self): @@ -93,7 +93,8 @@ return a * b def f(x): return g((x+1, x-1)) - graph = self.check(f, [int], [10], 99) + graph = self.check(f, [int], [10], 99, + expected_calls=1) # not inlined def test_direct_call_mutable_simple(self): A = lltype.GcStruct('A', ('x', lltype.Signed)) @@ -104,9 +105,8 @@ a.x = x g(a) return a.x - graph = self.check(f, [int], [41], 42) - insns = summary(graph) - assert insns.get('direct_call', 0) == 0 # no more call, inlined + graph = self.check(f, [int], [41], 42, + expected_calls=0) # no more call, inlined def test_direct_call_mutable_retval(self): A = lltype.GcStruct('A', ('x', lltype.Signed)) @@ -118,9 +118,8 @@ a.x = x y = g(a) return a.x + y - graph = self.check(f, [int], [41], 4242) - insns = summary(graph) - assert insns.get('direct_call', 0) == 0 # no more call, inlined + graph = self.check(f, [int], [41], 4242, + expected_calls=0) # no more call, inlined def test_direct_call_mutable_ret_virtual(self): A = lltype.GcStruct('A', ('x', lltype.Signed)) @@ -132,9 +131,8 @@ a.x = x b = g(a) return a.x + b.x - graph = self.check(f, [int], [41], 84) - insns = summary(graph) - assert insns.get('direct_call', 0) == 0 # no more call, inlined + graph = self.check(f, [int], [41], 84, + expected_calls=0) # no more call, inlined def test_direct_call_mutable_lastref(self): A = lltype.GcStruct('A', ('x', lltype.Signed)) @@ -146,9 +144,8 @@ a.x = x y = g(a) return x - y - graph = self.check(f, [int], [5], -45) - insns = summary(graph) - assert insns.get('direct_call', 0) == 1 # not inlined + graph = self.check(f, [int], [5], -45, + expected_calls=1) # not inlined def test_direct_call_ret_virtual(self): A = lltype.GcStruct('A', ('x', lltype.Signed)) @@ -162,9 +159,8 @@ a.x = 2 a = g(a) return prebuilt_a.x * a.x - graph = self.check(f, [int], [19], 42) - insns = summary(graph) - assert insns.get('direct_call', 0) == 0 # inlined + graph = self.check(f, [int], [19], 42, + expected_calls=0) # inlined def test_fn2(self): class T: @@ -224,6 +220,13 @@ return a1.x self.check(fn6, [int], [1], 12) + def test_with__del__(self): + class A(object): + def __del__(self): + pass + def fn7(): + A() + self.check(fn7, [], [], None, expected_mallocs=1) # don't remove class TestLLTypeMallocRemoval(BaseMallocRemovalTest): From arigo at codespeak.net Fri Oct 10 10:43:13 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 10:43:13 +0200 (CEST) Subject: [pypy-svn] r58876 - pypy/branch/2.5-merge/pypy/module/thread Message-ID: <20081010084313.F0AC6169EC1@codespeak.net> Author: arigo Date: Fri Oct 10 10:43:13 2008 New Revision: 58876 Modified: pypy/branch/2.5-merge/pypy/module/thread/__init__.py pypy/branch/2.5-merge/pypy/module/thread/app_thread.py Log: (fijal, arigo) Dummy thread.stack_size() implementation, which is needed to import e.g. 'threading'. Modified: pypy/branch/2.5-merge/pypy/module/thread/__init__.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/thread/__init__.py (original) +++ pypy/branch/2.5-merge/pypy/module/thread/__init__.py Fri Oct 10 10:43:13 2008 @@ -7,6 +7,7 @@ 'exit': 'app_thread.exit', 'exit_thread': 'app_thread.exit', # obsolete synonym 'error': 'app_thread.error', + 'stack_size': 'app_thread.stack_size', } interpleveldefs = { Modified: pypy/branch/2.5-merge/pypy/module/thread/app_thread.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/thread/app_thread.py (original) +++ pypy/branch/2.5-merge/pypy/module/thread/app_thread.py Fri Oct 10 10:43:13 2008 @@ -5,3 +5,6 @@ """This is synonymous to ``raise SystemExit''. It will cause the current thread to exit silently unless the exception is caught.""" raise SystemExit + +def stack_size(size=0): + raise error("not implemented") From fijal at codespeak.net Fri Oct 10 10:51:42 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 10:51:42 +0200 (CEST) Subject: [pypy-svn] r58877 - pypy/branch/2.5-merge/pypy/module/bz2 Message-ID: <20081010085142.F3D10169E91@codespeak.net> Author: fijal Date: Fri Oct 10 10:51:42 2008 New Revision: 58877 Modified: pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py Log: Fix translation (possibly there are more places) Modified: pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py (original) +++ pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py Fri Oct 10 10:51:42 2008 @@ -183,7 +183,7 @@ stream = open_bz2file_as_stream(self.space, name, mode, buffering, compresslevel) fd = stream.try_to_find_file_descriptor() - self.fdopenstream(stream, fd, mode, name) + self.fdopenstream(stream, fd, mode, space.wrap(name)) _exposed_method_names = [] W_File._decl.im_func(locals(), "bz2__init__", ['self', str, str, int, int], From fijal at codespeak.net Fri Oct 10 10:57:19 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 10:57:19 +0200 (CEST) Subject: [pypy-svn] r58878 - in pypy/branch/2.5-merge/pypy/module/bz2: . test Message-ID: <20081010085719.304C5169EA0@codespeak.net> Author: fijal Date: Fri Oct 10 10:57:18 2008 New Revision: 58878 Modified: pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py pypy/branch/2.5-merge/pypy/module/bz2/test/test_bz2_file.py Log: Fix tests and translation Modified: pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py (original) +++ pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py Fri Oct 10 10:57:18 2008 @@ -173,20 +173,20 @@ class W_BZ2File(W_File): - def direct_bz2__init__(self, name, mode='r', buffering=-1, + def direct_bz2__init__(self, w_name, mode='r', buffering=-1, compresslevel=9): self.direct_close() # the stream should always be opened in binary mode if "b" not in mode: mode = mode + "b" self.check_mode_ok(mode) - stream = open_bz2file_as_stream(self.space, name, mode, + stream = open_bz2file_as_stream(self.space, w_name, mode, buffering, compresslevel) fd = stream.try_to_find_file_descriptor() - self.fdopenstream(stream, fd, mode, space.wrap(name)) + self.fdopenstream(stream, fd, mode, w_name) _exposed_method_names = [] - W_File._decl.im_func(locals(), "bz2__init__", ['self', str, str, int, int], + W_File._decl.im_func(locals(), "bz2__init__", ['self', W_Root, str, int, int], """Opens a BZ2-compressed file.""") # XXX ^^^ hacking hacking... can't just use the name "__init__" again # because the RTyper is confused about the two direct__init__() with @@ -205,7 +205,7 @@ def descr_bz2file__new__(space, w_subtype, args): bz2file = space.allocate_instance(W_BZ2File, w_subtype) - W_BZ2File.__init__(bz2file, space) + W_BZ2File.__init__(space.wrap(bz2file), space) return space.wrap(bz2file) descr_bz2file__new__.unwrap_spec = [ObjSpace, W_Root, Arguments] @@ -240,7 +240,7 @@ # ____________________________________________________________ -def open_bz2file_as_stream(space, path, mode="r", buffering=-1, +def open_bz2file_as_stream(space, w_path, mode="r", buffering=-1, compresslevel=9): from pypy.rlib.streamio import decode_mode, open_path_helper from pypy.rlib.streamio import construct_stream_tower @@ -251,7 +251,7 @@ if basemode == "a": raise OperationError(space.w_ValueError, space.wrap("cannot append to bz2 file")) - stream = open_path_helper(path, os_flags, False) + stream = open_path_helper(space.str_w(w_path), os_flags, False) if reading: bz2stream = ReadBZ2Filter(space, stream, buffering) buffering = 0 # by construction, the ReadBZ2Filter acts like Modified: pypy/branch/2.5-merge/pypy/module/bz2/test/test_bz2_file.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/bz2/test/test_bz2_file.py (original) +++ pypy/branch/2.5-merge/pypy/module/bz2/test/test_bz2_file.py Fri Oct 10 10:57:18 2008 @@ -64,7 +64,7 @@ from bz2 import BZ2File raises(ValueError, BZ2File, self.temppath, mode='w', compresslevel=10) - raises(IOError, BZ2File, self.temppath, mode='XYZ') + raises(ValueError, BZ2File, self.temppath, mode='XYZ') # XXX the following is fine, currently: #raises(ValueError, BZ2File, self.temppath, mode='ww') From cfbolz at codespeak.net Fri Oct 10 11:09:25 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 10 Oct 2008 11:09:25 +0200 (CEST) Subject: [pypy-svn] r58879 - pypy/extradoc/sprintinfo/october-2008 Message-ID: <20081010090925.07165169E90@codespeak.net> Author: cfbolz Date: Fri Oct 10 11:09:25 2008 New Revision: 58879 Modified: pypy/extradoc/sprintinfo/october-2008/planning.txt Log: (all): planning for today Modified: pypy/extradoc/sprintinfo/october-2008/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/october-2008/planning.txt (original) +++ pypy/extradoc/sprintinfo/october-2008/planning.txt Fri Oct 10 11:09:25 2008 @@ -19,49 +19,38 @@ loops are working now - - merge the pypy-pytrunk branch DONE: merged and removed - - - run translation and the CPython tests through buildbot on pypy-c - BASICALLY DONE: buildmaster on codespeak now - - - cleanup wyvern (Samuele) - - - ask bigdog to add his machines + - cleanup wyvern DONE - add a py.test -A builder - look at the TODO list of the buildbot stuff - - merge the 2.5 branch (Maciek, Jakub) - - fix pypy/module bugs: BASICALLY DONE - - update stdlib to 2.5.2 DONE + - merge the 2.5 branch (Armin, Anto, Iko) - fix more CPython tests IN-PROGRESS - - finish set stuff (Iko, Carl Friedrich) - + - fix translation (Iko, Carl Friedrich) - - looking at the static data of pypy-c BASICALLY DONE, integration needed - (Alexander, Anto) - - malloc-removal-directed inlining to reduce the code size NEW APPROACH NEEDED + - malloc-removal-directed inlining to reduce the code size SOME PROGRESS - measuring memory behaviour - run memory-benchmarks nightly? - - merge gc-experiments branch (Carl Friedrich, Maciek) + - merge gc-experiments branch DONE - - builtin-profiling branch needs to be merged + - builtin-profiling branch needs to be merged (Armin, Anto) - - py-lib needs some fixes about pdb DONE - - - - setting up a scratchbox environment (Alexander, Holger) + - setting up a scratchbox environment DONE - measuring startup behaviour (Alexander, Holger) + - add code to print statistics to mark-and-compact (Alexander, Holger, Carl Friedrich) + + - cbuild.py refactoring (Maciek, Samuele) + Discussion Tasks: - JIT roadmap - C++ bindings? - - release plans, goals + - release plans, goals at 17.00 today From fijal at codespeak.net Fri Oct 10 11:11:18 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 11:11:18 +0200 (CEST) Subject: [pypy-svn] r58880 - pypy/branch/cbuild-refactor Message-ID: <20081010091118.3E43E169E90@codespeak.net> Author: fijal Date: Fri Oct 10 11:11:16 2008 New Revision: 58880 Added: pypy/branch/cbuild-refactor/ - copied from r58879, pypy/dist/ Log: New branch to fight distutils From arigo at codespeak.net Fri Oct 10 11:13:21 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 11:13:21 +0200 (CEST) Subject: [pypy-svn] r58881 - pypy/branch/2.5-merge/pypy/lib Message-ID: <20081010091321.5957C169E90@codespeak.net> Author: arigo Date: Fri Oct 10 11:13:20 2008 New Revision: 58881 Modified: pypy/branch/2.5-merge/pypy/lib/_exceptions.py Log: Remove tabs. Modified: pypy/branch/2.5-merge/pypy/lib/_exceptions.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/_exceptions.py (original) +++ pypy/branch/2.5-merge/pypy/lib/_exceptions.py Fri Oct 10 11:13:20 2008 @@ -65,8 +65,8 @@ +-- SyntaxWarning +-- UserWarning +-- FutureWarning - +-- ImportWarning - +-- UnicodeWarning + +-- ImportWarning + +-- UnicodeWarning """ class BaseException(object): From arigo at codespeak.net Fri Oct 10 11:14:47 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 11:14:47 +0200 (CEST) Subject: [pypy-svn] r58882 - pypy/branch/2.5-merge/pypy/interpreter/test Message-ID: <20081010091447.3A2C7169E90@codespeak.net> Author: arigo Date: Fri Oct 10 11:14:46 2008 New Revision: 58882 Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py Log: Make this importable on top of CPython 2.4. Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py Fri Oct 10 11:14:46 2008 @@ -273,7 +273,7 @@ import warnings warnings.simplefilter('error', SyntaxWarning) - 1 if True else 2 + exec "1 if True else 2" warnings.simplefilter('default', SyntaxWarning) From arigo at codespeak.net Fri Oct 10 11:17:35 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 11:17:35 +0200 (CEST) Subject: [pypy-svn] r58883 - pypy/branch/2.5-merge/pypy/interpreter/astcompiler/test Message-ID: <20081010091735.832C9168414@codespeak.net> Author: arigo Date: Fri Oct 10 11:17:35 2008 New Revision: 58883 Modified: pypy/branch/2.5-merge/pypy/interpreter/astcompiler/test/test_compiler.py Log: Fix test. Modified: pypy/branch/2.5-merge/pypy/interpreter/astcompiler/test/test_compiler.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/astcompiler/test/test_compiler.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/astcompiler/test/test_compiler.py Fri Oct 10 11:17:35 2008 @@ -616,6 +616,7 @@ def make_boundmethod(func=func): def boundmethod(*args): return func(self, *args) + r = None """) decl = str(decl) + '\n' yield self.simple_test, decl, 'r', None From iko at codespeak.net Fri Oct 10 11:32:35 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 10 Oct 2008 11:32:35 +0200 (CEST) Subject: [pypy-svn] r58885 - pypy/branch/2.5-merge/pypy/module/bz2 Message-ID: <20081010093235.CBB28169EEC@codespeak.net> Author: iko Date: Fri Oct 10 11:32:34 2008 New Revision: 58885 Modified: pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py Log: (iko,cfbolz) fix translation failure in bz2 Modified: pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py (original) +++ pypy/branch/2.5-merge/pypy/module/bz2/interp_bz2.py Fri Oct 10 11:32:34 2008 @@ -205,7 +205,7 @@ def descr_bz2file__new__(space, w_subtype, args): bz2file = space.allocate_instance(W_BZ2File, w_subtype) - W_BZ2File.__init__(space.wrap(bz2file), space) + W_BZ2File.__init__(bz2file, space) return space.wrap(bz2file) descr_bz2file__new__.unwrap_spec = [ObjSpace, W_Root, Arguments] From hpk at codespeak.net Fri Oct 10 11:43:53 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 10 Oct 2008 11:43:53 +0200 (CEST) Subject: [pypy-svn] r58886 - pypy/dist/pypy/rpython/memory/gc Message-ID: <20081010094353.AFE6E169E96@codespeak.net> Author: hpk Date: Fri Oct 10 11:43:53 2008 New Revision: 58886 Modified: pypy/dist/pypy/rpython/memory/gc/markcompact.py Log: (xoraxax,hpk) insert debug prints for collection time for markcompact Modified: pypy/dist/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/dist/pypy/rpython/memory/gc/markcompact.py Fri Oct 10 11:43:53 2008 @@ -1,4 +1,6 @@ +import time + from pypy.rpython.lltypesystem import lltype, llmemory, llarena from pypy.rpython.memory.gc.base import MovingGCBase from pypy.rlib.debug import ll_assert @@ -17,6 +19,8 @@ memoryError = MemoryError() +DEBUG_PRINT = True + # Mark'n'compact garbage collector # # main point of this GC is to save as much memory as possible @@ -62,6 +66,8 @@ inline_simple_malloc = True inline_simple_malloc_varsize = True first_unused_gcflag = first_gcflag << 2 + total_collection_time = 0.0 + total_collection_count = 0 def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096): MovingGCBase.__init__(self, chunk_size) @@ -69,6 +75,8 @@ self.red_zone = 0 def setup(self): + if DEBUG_PRINT: + self.program_start_time = time.time() self.space = llarena.arena_malloc(self.space_size, True) ll_assert(bool(self.space), "couldn't allocate arena") self.free = self.space @@ -174,8 +182,8 @@ def collect(self): self.markcompactcollect() - def markcompactcollect(self, resizing=False): + start_time = self.debug_collect_start() self.debug_check_consistency() if resizing: toaddr = self.tospace @@ -212,6 +220,40 @@ self.record_red_zone() if self.run_finalizers.non_empty(): self.execute_finalizers() + self.debug_collect_finish(start_time) + + def debug_collect_start(self): + if DEBUG_PRINT: + llop.debug_print(lltype.Void) + llop.debug_print(lltype.Void, + ".----------- Full collection ------------------") + start_time = time.time() + return start_time + + def debug_collect_finish(self, start_time): + if DEBUG_PRINT: + end_time = time.time() + elapsed_time = end_time - start_time + self.total_collection_time += elapsed_time + self.total_collection_count += 1 + total_program_time = end_time - self.program_start_time + ct = self.total_collection_time + cc = self.total_collection_count + llop.debug_print(lltype.Void, + "| number of collections so far ", + cc) + llop.debug_print(lltype.Void, + "| total collections per second: ", + cc / total_program_time) + llop.debug_print(lltype.Void, + "| total time in markcompact-collect: ", + ct, "seconds") + llop.debug_print(lltype.Void, + "| percentage collection<->total time:", + ct * 100.0 / total_program_time, "%") + llop.debug_print(lltype.Void, + "`----------------------------------------------") + def update_run_finalizers(self): run_finalizers = self.AddressDeque() From xoraxax at codespeak.net Fri Oct 10 11:46:33 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 10 Oct 2008 11:46:33 +0200 (CEST) Subject: [pypy-svn] r58887 - pypy/dist/pypy/rlib Message-ID: <20081010094633.32033169E96@codespeak.net> Author: xoraxax Date: Fri Oct 10 11:46:32 2008 New Revision: 58887 Modified: pypy/dist/pypy/rlib/pyplatform.py Log: Add arm6 scratchbox path to pyplatform. Modified: pypy/dist/pypy/rlib/pyplatform.py ============================================================================== --- pypy/dist/pypy/rlib/pyplatform.py (original) +++ pypy/dist/pypy/rlib/pyplatform.py Fri Oct 10 11:46:32 2008 @@ -38,6 +38,7 @@ if cc is None: for x in ( '/scratchbox/compilers/cs2007q3-glibc2.5-arm7/bin/arm-none-linux-gnueabi-gcc', + '/scratchbox/compilers/cs2007q3-glibc2.5-arm6/bin/arm-none-linux-gnueabi-gcc', '/scratchbox/compilers/cs2005q3.2-glibc-arm/bin/sbox-arm-linux-gcc', ): if py.path.local(x).check(): From fijal at codespeak.net Fri Oct 10 12:05:19 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 12:05:19 +0200 (CEST) Subject: [pypy-svn] r58889 - in pypy/branch/cbuild-refactor/pypy/translator: c tool Message-ID: <20081010100519.8F72D169E3C@codespeak.net> Author: fijal Date: Fri Oct 10 12:05:19 2008 New Revision: 58889 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Log: (pedronis, fijal) Try to unify two ways we were using distutils Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Fri Oct 10 12:05:19 2008 @@ -135,14 +135,6 @@ if CBuilder.have___thread: if not self.config.translation.no__thread: defines['USE___THREAD'] = 1 - # explicitely include python.h and exceptions.h - # XXX for now, we always include Python.h - from distutils import sysconfig - python_inc = sysconfig.get_python_inc() - pypy_include_dir = autopath.this_dir - self.eci = self.eci.merge(ExternalCompilationInfo( - include_dirs=[python_inc, pypy_include_dir], - )) cfile, extra = gen_source_standalone(db, modulename, targetdir, self.eci, entrypointname = pfname, Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Fri Oct 10 12:05:19 2008 @@ -300,150 +300,21 @@ opt += '/Op' gcv['OPT'] = opt -def compile_c_module(cfiles, modbasename, eci, tmpdir=None): - #try: - # from distutils.log import set_threshold - # set_threshold(10000) - #except ImportError: - # print "ERROR IMPORTING" - # pass - cfiles = [py.path.local(f) for f in cfiles] - if tmpdir is None: - tmpdir = udir.join("module_cache").ensure(dir=1) - num = 0 - cfiles += eci.separate_module_files - include_dirs = list(eci.include_dirs) - include_dirs.append(py.path.local(pypydir).join('translator', 'c')) - library_dirs = list(eci.library_dirs) - if sys.platform == 'darwin': # support Fink & Darwinports - for s in ('/sw/', '/opt/local/'): - if s + 'include' not in include_dirs and \ - os.path.exists(s + 'include'): - include_dirs.append(s + 'include') - if s + 'lib' not in library_dirs and \ - os.path.exists(s + 'lib'): - library_dirs.append(s + 'lib') - - export_symbols = list(eci.export_symbols) - - num = 0 +def next_unique_name(modbasename, tmpdir): modname = modbasename while 1: if not tmpdir.join(modname + so_ext).check(): break num += 1 modname = '%s_%d' % (modbasename, num) + return modname - lastdir = tmpdir.chdir() - libraries = eci.libraries - ensure_correct_math() - try: - if debug: print "modname", modname - c = stdoutcapture.Capture(mixed_out_err = True) - try: - try: - if compiler_command(): - # GCC-ish options only - from distutils import sysconfig - gcv = sysconfig.get_config_vars() - cmd = compiler_command().replace('%s', - str(tmpdir.join(modname))) - for dir in [gcv['INCLUDEPY']] + list(include_dirs): - cmd += ' -I%s' % dir - for dir in library_dirs: - cmd += ' -L%s' % dir - os.system(cmd) - else: - from distutils.dist import Distribution - from distutils.extension import Extension - from distutils.ccompiler import get_default_compiler - from distutils.command.build_ext import build_ext - - class build_shared_library(build_ext): - """ We build shared libraries, not python modules. - On windows, avoid to export the initXXX function, - and don't use a .pyd extension. """ - def get_export_symbols(self, ext): - return ext.export_symbols - def get_ext_filename (self, ext_name): - if sys.platform == 'win32': - return ext_name + ".dll" - else: - return ext_name + ".so" - - saved_environ = os.environ.items() - try: - # distutils.core.setup() is really meant for end-user - # interactive usage, because it eats most exceptions and - # turn them into SystemExits. Instead, we directly - # instantiate a Distribution, which also allows us to - # ignore unwanted features like config files. - extra_compile_args = [] - # ensure correct math on windows - if sys.platform == 'win32': - extra_compile_args.append('/Op') # get extra precision - if get_default_compiler() == 'unix': - old_version = False - try: - g = os.popen('gcc --version', 'r') - verinfo = g.read() - g.close() - except (OSError, IOError): - pass - else: - old_version = verinfo.startswith('2') - if not old_version: - extra_compile_args.extend(["-Wno-unused-label", - "-Wno-unused-variable"]) - attrs = { - 'name': "testmodule", - 'ext_modules': [ - Extension(modname, [str(cfile) for cfile in cfiles], - include_dirs=include_dirs, - library_dirs=library_dirs, - extra_compile_args=extra_compile_args, - libraries=list(libraries), - export_symbols=export_symbols, - ) - ], - 'script_name': 'setup.py', - 'script_args': ['-q', 'build_ext'], # don't remove 'build_ext' here - } - dist = Distribution(attrs) - # patch our own command obj into distutils - # because it does not have a facility to accept - # custom objects - cmdobj = build_shared_library(dist) - cmdobj.inplace = True - cmdobj.force = True - if (sys.platform == 'win32' - and sys.executable.lower().endswith('_d.exe')): - cmdobj.debug = True - dist.command_obj["build_ext"] = cmdobj - dist.have_run["build_ext"] = 0 - - if not dist.parse_command_line(): - raise ValueError, "distutils cmdline parse error" - dist.run_commands() - finally: - for key, value in saved_environ: - if os.environ.get(key) != value: - os.environ[key] = value - finally: - foutput, foutput = c.done() - data = foutput.read() - if data: - fdump = open("%s.errors" % modname, "w") - fdump.write(data) - fdump.close() - # XXX do we need to do some check on fout/ferr? - # XXX not a nice way to import a module - except: - print >>sys.stderr, data - raise - finally: - lastdir.chdir() - return str(tmpdir.join(modname) + so_ext) +def compile_c_module(cfiles, modbasename, eci, tmpdir=None): + eci = eci.convert_sources_to_files() + cfiles.extend(eci.separate_module_files) + compiler = CCompiler(cfiles, eci, standalone=False) + compiler.build() + return str(compiler.outputfilename) def make_module_from_c(cfile, eci): cfile = py.path.local(cfile) @@ -504,9 +375,20 @@ fix_gcc_random_seed = False def __init__(self, cfilenames, eci, outputfilename=None, - compiler_exe=None, profbased=None): + compiler_exe=None, profbased=None, standalone=True): + from distutils import sysconfig + python_inc = sysconfig.get_python_inc() + pypy_include_dir = py.path.local(autopath.pypydir).join('translator', 'c') + eci = eci.merge(ExternalCompilationInfo( + include_dirs=[python_inc, pypy_include_dir], + platform=eci.platform, + )) self.cfilenames = cfilenames - ext = '' + if standalone: + ext = '' + else: + ext = so_ext + self.standalone = standalone self.libraries = list(eci.libraries) self.include_dirs = list(eci.include_dirs) self.library_dirs = list(eci.library_dirs) @@ -628,10 +510,14 @@ finally: old.chdir() - compiler.link_executable(objects, str(self.outputfilename), - libraries=self.eci.libraries, - extra_preargs=self.link_extra, - library_dirs=self.eci.library_dirs) + if self.standalone: + cmd = compiler.link_executable + else: + cmd = compiler.link_shared_object + cmd(objects, str(self.outputfilename), + libraries=self.eci.libraries, + extra_preargs=self.link_extra, + library_dirs=self.eci.library_dirs) def build_executable(*args, **kwds): noerr = kwds.pop('noerr', False) From arigo at codespeak.net Fri Oct 10 12:10:04 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 12:10:04 +0200 (CEST) Subject: [pypy-svn] r58890 - pypy/branch/2.5-merge/pypy/rpython/module/test Message-ID: <20081010101004.413DC169E3C@codespeak.net> Author: arigo Date: Fri Oct 10 12:10:03 2008 New Revision: 58890 Removed: pypy/branch/2.5-merge/pypy/rpython/module/test/execve_tests.py Modified: pypy/branch/2.5-merge/pypy/rpython/module/test/test_ll_os.py Log: (antocuni, arigo) Change the style of the test to use fork() instead of os.system() so that the sys.path is preserved. Modified: pypy/branch/2.5-merge/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/branch/2.5-merge/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/branch/2.5-merge/pypy/rpython/module/test/test_ll_os.py Fri Oct 10 12:10:03 2008 @@ -64,41 +64,62 @@ EXECVE_ENV = {"foo": "bar", "baz": "quux"} -execve_tests = str(local(__file__).dirpath().join('execve_tests.py')) def test_execve(): if os.name != 'posix': py.test.skip('posix specific function') - base = " ".join([ - sys.executable, - execve_tests, - str(local(pypy.__file__).join('..', '..')), - '']) + + ll_execve = getllimpl(os.execve) + + def run_execve(program, env): + # we cannot directly call ll_execve() because it replaces the + # current process. + fd_read, fd_write = os.pipe() + childpid = os.fork() + if childpid == 0: + # in the child + os.close(fd_read) + os.dup2(fd_write, 1) # stdout + os.close(fd_write) + ll_execve(program, [program], env) + assert 0, "should not arrive here" + else: + # in the parent + os.close(fd_write) + child_stdout = [] + while True: + data = os.read(fd_read, 4096) + if not data: break # closed + child_stdout.append(data) + pid, status = os.waitpid(childpid, 0) + os.close(fd_read) + return status, ''.join(child_stdout) # Test exit status and code - result = os.system(base + "execve_true") + result, child_stdout = run_execve("/bin/true", {}) assert os.WIFEXITED(result) assert os.WEXITSTATUS(result) == 0 - result = os.system(base + "execve_false") + result, child_stdout = run_execve("/bin/false", {}) assert os.WIFEXITED(result) assert os.WEXITSTATUS(result) == 1 # Test environment - result = os.popen(base + "execve_env").read() - assert dict([line.split('=') for line in result.splitlines()]) == EXECVE_ENV + result, child_stdout = run_execve("/usr/bin/env", EXECVE_ENV) + assert os.WIFEXITED(result) + assert os.WEXITSTATUS(result) == 0 + assert dict([line.split('=') for line in child_stdout.splitlines()]) == EXECVE_ENV - # These won't actually execute anything, so they don't need a child process - # helper. - execve = getllimpl(os.execve) + # The following won't actually execute anything, so they don't need + # a child process helper. # If the target does not exist, an OSError should result info = py.test.raises( - OSError, execve, execve_tests + "-non-existent", [], {}) + OSError, ll_execve, "this/file/is/non/existent", [], {}) assert info.value.errno == errno.ENOENT # If the target is not executable, an OSError should result info = py.test.raises( - OSError, execve, execve_tests, [], {}) + OSError, ll_execve, "/etc/passwd", [], {}) assert info.value.errno == errno.EACCES From antocuni at codespeak.net Fri Oct 10 12:11:11 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 10 Oct 2008 12:11:11 +0200 (CEST) Subject: [pypy-svn] r58891 - pypy/dist/pypy/doc Message-ID: <20081010101111.26986169E41@codespeak.net> Author: antocuni Date: Fri Oct 10 12:11:08 2008 New Revision: 58891 Added: pypy/dist/pypy/doc/externaltools.txt (contents, props changed) Log: (antocuni, arigo) list the dependencies needed to be installed on the slaves in order to run all the tests Added: pypy/dist/pypy/doc/externaltools.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/externaltools.txt Fri Oct 10 12:11:08 2008 @@ -0,0 +1,27 @@ +External tools&programs needed by PyPy +====================================== + +Tools needed for testing +------------------------ + +These tools are used in various ways by PyPy tests; if they are not found, +some tests might be skipped, so they need to be installed on every buildbot +slave to be sure we actually run all tests: + + - Mono (versions 1.2.1.1 and 1.9.1 known to work) + + - Java/JVM (preferably sun-jdk; version 1.6.0 known to work) + + - Jasmin >= 2.2 (copy it from wyvern, /usr/local/bin/jasmin and /usr/local/share/jasmin.jar) + + - gcc + + - Some libraries (these are Debian package names, adapt as needed): + + * ``python-dev`` + * ``python-ctypes`` + * ``libffi-dev`` + * ``libz-dev`` (for the optional ``zlib`` module) + * ``libbz2-dev`` (for the optional ``bz2`` module) + * ``libncurses-dev`` (for the optional ``_minimal_curses`` module) + * ``libgc-dev`` (only when translating with `--opt=0, 1` or `size`) From arigo at codespeak.net Fri Oct 10 12:11:48 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 12:11:48 +0200 (CEST) Subject: [pypy-svn] r58892 - pypy/branch/2.5-merge/pypy/lib/app_test Message-ID: <20081010101148.447AA169E41@codespeak.net> Author: arigo Date: Fri Oct 10 12:11:47 2008 New Revision: 58892 Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_datetime.py Log: Fix test. Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_datetime.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/app_test/test_datetime.py (original) +++ pypy/branch/2.5-merge/pypy/lib/app_test/test_datetime.py Fri Oct 10 12:11:47 2008 @@ -1,5 +1,5 @@ -import datetime +from pypy.lib import datetime def test_repr(): print datetime From arigo at codespeak.net Fri Oct 10 12:15:57 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 12:15:57 +0200 (CEST) Subject: [pypy-svn] r58893 - pypy/branch/2.5-merge/pypy/lib/app_test Message-ID: <20081010101557.2CCF5169E54@codespeak.net> Author: arigo Date: Fri Oct 10 12:15:56 2008 New Revision: 58893 Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py Log: (antocuni, arigo) Skip these tests on top of 2.3 or 2.4. Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py (original) +++ pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py Fri Oct 10 12:15:56 2008 @@ -1,12 +1,14 @@ # defaultdict Tests # from CPython2.5 -import copy +import sys +if sys.version_info < (2, 5): + import py + # the app-level defaultdict relies on the interp-level dict + # calling __missing__() + py.test.skip("these tests only run on top of CPython 2.5") -# for passing the test on top of 2.3 -from py.builtin import reversed -import pypy.lib.collections -pypy.lib.collections.reversed = reversed +import copy from pypy.lib.collections import defaultdict From arigo at codespeak.net Fri Oct 10 12:25:17 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 12:25:17 +0200 (CEST) Subject: [pypy-svn] r58894 - pypy/branch/2.5-merge/pypy/module/_file/test Message-ID: <20081010102517.D1E61169E11@codespeak.net> Author: arigo Date: Fri Oct 10 12:25:17 2008 New Revision: 58894 Modified: pypy/branch/2.5-merge/pypy/module/_file/test/test_file.py Log: (antocuni, arigo) Fix the umask testing. Modified: pypy/branch/2.5-merge/pypy/module/_file/test/test_file.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_file/test/test_file.py (original) +++ pypy/branch/2.5-merge/pypy/module/_file/test/test_file.py Fri Oct 10 12:25:17 2008 @@ -94,13 +94,13 @@ def test_correct_file_mode(self): import os f = self.file(self.temppath, "w") - umask = os.umask(18) + umask = os.umask(0) os.umask(umask) try: f.write("foo") finally: f.close() - assert oct(os.stat(self.temppath).st_mode & 0777 | umask) == oct(0666) + assert oct(os.stat(self.temppath).st_mode & 0777) == oct(0666 & ~umask) def test_newlines(self): import os From pedronis at codespeak.net Fri Oct 10 12:51:40 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 10 Oct 2008 12:51:40 +0200 (CEST) Subject: [pypy-svn] r58895 - pypy/branch/cbuild-refactor/pypy/translator/tool Message-ID: <20081010105140.EDCE6169E54@codespeak.net> Author: pedronis Date: Fri Oct 10 12:51:40 2008 New Revision: 58895 Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Log: (fijal, pedronis) for now use distutils.sysconfig to customize the compiler to get the right options to build a shared lib things work again on Mac OS X Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Fri Oct 10 12:51:40 2008 @@ -479,11 +479,14 @@ def _build(self): from distutils.ccompiler import new_compiler + from distutils import sysconfig compiler = new_compiler(force=1) if self.compiler_exe is not None: for c in '''compiler compiler_so compiler_cxx linker_exe linker_so'''.split(): compiler.executables[c][0] = self.compiler_exe + if not self.standalone: + sysconfig.customize_compiler(compiler) # XXX compiler.spawn = log_spawned_cmd(compiler.spawn) objects = [] for cfile in self.cfilenames: From iko at codespeak.net Fri Oct 10 12:57:10 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 10 Oct 2008 12:57:10 +0200 (CEST) Subject: [pypy-svn] r58896 - in pypy/dist/pypy: config rpython/memory rpython/memory/gc rpython/memory/gc/test rpython/memory/gctransform Message-ID: <20081010105710.D08A216841E@codespeak.net> Author: iko Date: Fri Oct 10 12:57:08 2008 New Revision: 58896 Modified: pypy/dist/pypy/config/translationoption.py pypy/dist/pypy/rpython/memory/gc/base.py pypy/dist/pypy/rpython/memory/gc/generation.py pypy/dist/pypy/rpython/memory/gc/hybrid.py pypy/dist/pypy/rpython/memory/gc/markcompact.py pypy/dist/pypy/rpython/memory/gc/marksweep.py pypy/dist/pypy/rpython/memory/gc/semispace.py pypy/dist/pypy/rpython/memory/gc/test/test_direct.py pypy/dist/pypy/rpython/memory/gctransform/framework.py pypy/dist/pypy/rpython/memory/gcwrapper.py Log: (iko, cfbolz) Make GC debug print a tranlation option instead of a module level flag Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Fri Oct 10 12:57:08 2008 @@ -68,6 +68,10 @@ "ref": [("translation.gcrootfinder", "n/a")], "none": [("translation.gcrootfinder", "n/a")], }), + OptionDescription("gcconfig", "Configure garbage collectors", [ + BoolOption("debugprint", "Turn on debug printing for the GC", + default=False) + ]), ChoiceOption("gcrootfinder", "Strategy for finding GC Roots (framework GCs only)", ["n/a", "shadowstack", "llvmgc", "asmgcc"], Modified: pypy/dist/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/base.py (original) +++ pypy/dist/pypy/rpython/memory/gc/base.py Fri Oct 10 12:57:08 2008 @@ -14,12 +14,13 @@ prebuilt_gc_objects_are_static_roots = True can_realloc = False - def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE): + def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE): self.gcheaderbuilder = GCHeaderBuilder(self.HDR) self.AddressStack = get_address_stack(chunk_size) self.AddressDeque = get_address_deque(chunk_size) self.AddressDict = AddressDict self.finalizer_lock_count = 0 + self.config = config def can_malloc_nonmovable(self): return not self.moving_gc Modified: pypy/dist/pypy/rpython/memory/gc/generation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/generation.py (original) +++ pypy/dist/pypy/rpython/memory/gc/generation.py Fri Oct 10 12:57:08 2008 @@ -1,7 +1,6 @@ import sys from pypy.rpython.memory.gc.semispace import SemiSpaceGC from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED -from pypy.rpython.memory.gc.semispace import DEBUG_PRINT from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage from pypy.rpython.lltypesystem import lltype, llmemory, llarena from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE @@ -42,13 +41,13 @@ 'min_nursery_size': 48*1024, 'auto_nursery_size': True} - def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, + def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, nursery_size=128, min_nursery_size=128, auto_nursery_size=False, space_size=4096, max_space_size=sys.maxint//2+1): - SemiSpaceGC.__init__(self, chunk_size = chunk_size, + SemiSpaceGC.__init__(self, config, chunk_size = chunk_size, space_size = space_size, max_space_size = max_space_size) assert min_nursery_size <= nursery_size <= space_size // 2 @@ -81,7 +80,8 @@ if self.auto_nursery_size: newsize = nursery_size_from_env() if newsize <= 0: - newsize = estimate_best_nursery_size() + newsize = estimate_best_nursery_size( + self.config.gcconfig.debugprint) if newsize > 0: self.set_nursery_size(newsize) @@ -105,7 +105,7 @@ while (self.min_nursery_size << (scale+1)) <= newsize: scale += 1 self.nursery_scale = scale - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, "SSS nursery_size =", newsize) llop.debug_print(lltype.Void, "SSS largest_young_fixedsize =", self.largest_young_fixedsize) @@ -228,10 +228,10 @@ self.weakrefs_grow_older() self.ids_grow_older() self.reset_nursery() - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, "major collect, size changing", size_changing) SemiSpaceGC.semispace_collect(self, size_changing) - if DEBUG_PRINT and not size_changing: + if self.config.gcconfig.debugprint and not size_changing: llop.debug_print(lltype.Void, "percent survived", float(self.free - self.tospace) / self.space_size) def make_a_copy(self, obj, objsize): @@ -310,7 +310,7 @@ ll_assert(self.nursery_size <= self.top_of_space - self.free, "obtain_free_space failed to do its job") if self.nursery: - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, "minor collect") # a nursery-only collection scan = beginning = self.free @@ -325,7 +325,7 @@ self.update_young_objects_with_id() # mark the nursery as free and fill it with zeroes again llarena.arena_reset(self.nursery, self.nursery_size, True) - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, "percent survived:", float(scan - beginning) / self.nursery_size) #self.debug_check_consistency() # -- quite expensive else: @@ -352,7 +352,7 @@ hdr = self.header(obj) hdr.tid |= GCFLAG_NO_YOUNG_PTRS self.trace_and_drag_out_of_nursery(obj) - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, "collect_oldrefs_to_nursery", count) def collect_roots_in_nursery(self): @@ -529,8 +529,8 @@ pass return -1 -def best_nursery_size_for_L2cache(L2cache): - if DEBUG_PRINT: +def best_nursery_size_for_L2cache(L2cache, debugprint=False): + if debugprint: llop.debug_print(lltype.Void, "CCC L2cache =", L2cache) # Heuristically, the best nursery size to choose is about half # of the L2 cache. XXX benchmark some more. @@ -538,7 +538,7 @@ if sys.platform == 'linux2': - def estimate_best_nursery_size(): + def estimate_best_nursery_size(debugprint=False): """Try to estimate the best nursery size at run-time, depending on the machine we are running on. """ @@ -590,7 +590,7 @@ L2cache = number if L2cache < sys.maxint: - return best_nursery_size_for_L2cache(L2cache) + return best_nursery_size_for_L2cache(L2cache, debugprint) else: # Print a warning even in non-debug builds llop.debug_print(lltype.Void, @@ -617,7 +617,7 @@ rffi.INT, sandboxsafe=True) - def estimate_best_nursery_size(): + def estimate_best_nursery_size(debugprint=False): """Try to estimate the best nursery size at run-time, depending on the machine we are running on. """ @@ -645,7 +645,7 @@ finally: lltype.free(l2cache_p, flavor='raw') if L2cache > 0: - return best_nursery_size_for_L2cache(L2cache) + return best_nursery_size_for_L2cache(L2cache, debugprint) else: # Print a warning even in non-debug builds llop.debug_print(lltype.Void, @@ -653,5 +653,5 @@ return -1 else: - def estimate_best_nursery_size(): + def estimate_best_nursery_size(debugprint=False): return -1 # XXX implement me for other platforms Modified: pypy/dist/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/dist/pypy/rpython/memory/gc/hybrid.py Fri Oct 10 12:57:08 2008 @@ -1,6 +1,5 @@ import sys from pypy.rpython.memory.gc.semispace import SemiSpaceGC -from pypy.rpython.memory.gc.semispace import DEBUG_PRINT from pypy.rpython.memory.gc.generation import GenerationGC from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED from pypy.rpython.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS @@ -115,7 +114,7 @@ assert self.nonlarge_gcptrs_max <= self.lb_young_var_basesize assert self.nonlarge_max <= self.nonlarge_gcptrs_max self.large_objects_collect_trigger = self.space_size - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: self._initial_trigger = self.large_objects_collect_trigger self.rawmalloced_objects_to_trace = self.AddressStack() self.count_semispaceonly_collects = 0 @@ -270,7 +269,7 @@ def _check_rawsize_alloced(self, size_estimate, can_collect=True): self.large_objects_collect_trigger -= size_estimate if can_collect and self.large_objects_collect_trigger < 0: - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, "allocated", self._initial_trigger - self.large_objects_collect_trigger, @@ -339,7 +338,7 @@ None) ll_assert(not self.rawmalloced_objects_to_trace.non_empty(), "rawmalloced_objects_to_trace should be empty at start") - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: self._nonmoving_copy_count = 0 self._nonmoving_copy_size = 0 @@ -414,7 +413,7 @@ newaddr = self.allocate_external_object(totalsize) if not newaddr: return llmemory.NULL # can't raise MemoryError during a collect() - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: self._nonmoving_copy_count += 1 self._nonmoving_copy_size += raw_malloc_usage(totalsize) @@ -450,7 +449,7 @@ def finished_full_collect(self): ll_assert(not self.rawmalloced_objects_to_trace.non_empty(), "rawmalloced_objects_to_trace should be empty at end") - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, "| [hybrid] made nonmoving: ", self._nonmoving_copy_size, "bytes in", @@ -465,7 +464,7 @@ self.large_objects_collect_trigger = self.space_size if self.is_collecting_gen3(): self.count_semispaceonly_collects = 0 - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: self._initial_trigger = self.large_objects_collect_trigger def sweep_rawmalloced_objects(self, generation): @@ -497,19 +496,21 @@ objects = self.gen2_resizable_objects surviving_objects = self.AddressStack() - if DEBUG_PRINT: alive_count = alive_size = 0 - if DEBUG_PRINT: dead_count = dead_size = 0 + # Help the flow space + alive_count = alive_size = dead_count = dead_size = 0 while objects.non_empty(): obj = objects.pop() tid = self.header(obj).tid if tid & GCFLAG_UNVISITED: - if DEBUG_PRINT:dead_count+=1 - if DEBUG_PRINT:dead_size+=raw_malloc_usage(self.get_size(obj)) + if self.config.gcconfig.debugprint: + dead_count+=1 + dead_size+=raw_malloc_usage(self.get_size(obj)) addr = obj - self.gcheaderbuilder.size_gc_header llmemory.raw_free(addr) else: - if DEBUG_PRINT:alive_count+=1 - if DEBUG_PRINT:alive_size+=raw_malloc_usage(self.get_size(obj)) + if self.config.gcconfig.debugprint: + alive_count+=1 + alive_size+=raw_malloc_usage(self.get_size(obj)) if generation == 3: surviving_objects.append(obj) elif generation == 2: @@ -538,7 +539,7 @@ self.gen3_rawmalloced_objects = surviving_objects elif generation == -2: self.gen2_resizable_objects = surviving_objects - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, "| [hyb] gen", generation, "nonmoving now alive: ", Modified: pypy/dist/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/dist/pypy/rpython/memory/gc/markcompact.py Fri Oct 10 12:57:08 2008 @@ -19,8 +19,6 @@ memoryError = MemoryError() -DEBUG_PRINT = True - # Mark'n'compact garbage collector # # main point of this GC is to save as much memory as possible @@ -69,13 +67,13 @@ total_collection_time = 0.0 total_collection_count = 0 - def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096): - MovingGCBase.__init__(self, chunk_size) + def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096): + MovingGCBase.__init__(self, config, chunk_size) self.space_size = space_size self.red_zone = 0 def setup(self): - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: self.program_start_time = time.time() self.space = llarena.arena_malloc(self.space_size, True) ll_assert(bool(self.space), "couldn't allocate arena") @@ -223,7 +221,7 @@ self.debug_collect_finish(start_time) def debug_collect_start(self): - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void) llop.debug_print(lltype.Void, ".----------- Full collection ------------------") @@ -231,7 +229,7 @@ return start_time def debug_collect_finish(self, start_time): - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: end_time = time.time() elapsed_time = end_time - start_time self.total_collection_time += elapsed_time Modified: pypy/dist/pypy/rpython/memory/gc/marksweep.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/marksweep.py (original) +++ pypy/dist/pypy/rpython/memory/gc/marksweep.py Fri Oct 10 12:57:08 2008 @@ -19,7 +19,6 @@ ('pool', X_POOL_PTR)) X_CLONE_PTR = lltype.Ptr(X_CLONE) -DEBUG_PRINT = False memoryError = MemoryError() class MarkSweepGC(GCBase): HDR = lltype.ForwardReference() @@ -41,8 +40,8 @@ # translating to a real backend. TRANSLATION_PARAMS = {'start_heap_size': 8*1024*1024} # XXX adjust - def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, start_heap_size=4096): - GCBase.__init__(self, chunk_size) + def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, start_heap_size=4096): + GCBase.__init__(self, config, chunk_size) self.heap_usage = 0 # at the end of the latest collection self.bytes_malloced = 0 # since the latest collection self.bytes_malloced_threshold = start_heap_size @@ -233,7 +232,7 @@ # call __del__, move the object to the list of object-without-del import time from pypy.rpython.lltypesystem.lloperation import llop - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, 'collecting...') start_time = time.time() self.collect_in_progress = True @@ -398,7 +397,7 @@ 256 * 1024 * 1024) self.total_collection_time += collect_time self.prev_collect_end_time = end_time - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void, " malloced since previous collection:", old_malloced, "bytes") Modified: pypy/dist/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/dist/pypy/rpython/memory/gc/semispace.py Fri Oct 10 12:57:08 2008 @@ -11,7 +11,7 @@ from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.memory.gc.base import MovingGCBase -import sys, os +import sys, os, time TYPEID_MASK = 0xffff first_gcflag = 1 << 16 @@ -21,7 +21,6 @@ GCFLAG_EXTERNAL = first_gcflag << 1 GCFLAG_FINALIZATION_ORDERING = first_gcflag << 2 -DEBUG_PRINT = False memoryError = MemoryError() class SemiSpaceGC(MovingGCBase): @@ -42,16 +41,15 @@ # translating to a real backend. TRANSLATION_PARAMS = {'space_size': 8*1024*1024} # XXX adjust - def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096, + def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096, max_space_size=sys.maxint//2+1): - MovingGCBase.__init__(self, chunk_size) + MovingGCBase.__init__(self, config, chunk_size) self.space_size = space_size self.max_space_size = max_space_size self.red_zone = 0 def setup(self): - if DEBUG_PRINT: - import time + if self.config.gcconfig.debugprint: self.program_start_time = time.time() self.tospace = llarena.arena_malloc(self.space_size, True) ll_assert(bool(self.tospace), "couldn't allocate tospace") @@ -197,8 +195,7 @@ # (this is also a hook for the HybridGC) def semispace_collect(self, size_changing=False): - if DEBUG_PRINT: - import time + if self.config.gcconfig.debugprint: llop.debug_print(lltype.Void) llop.debug_print(lltype.Void, ".----------- Full collection ------------------") @@ -210,6 +207,8 @@ #llop.debug_print(lltype.Void, 'semispace_collect', int(size_changing)) tospace = self.fromspace fromspace = self.tospace + start_time = 0 # Help the flow space + start_usage = 0 # Help the flow space self.fromspace = fromspace self.tospace = tospace self.top_of_space = tospace + self.space_size @@ -231,7 +230,7 @@ self.record_red_zone() self.execute_finalizers() #llop.debug_print(lltype.Void, 'collected', self.space_size, size_changing, self.top_of_space - self.free) - if DEBUG_PRINT: + if self.config.gcconfig.debugprint: end_time = time.time() elapsed_time = end_time - start_time self.total_collection_time += elapsed_time Modified: pypy/dist/pypy/rpython/memory/gc/test/test_direct.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/test/test_direct.py (original) +++ pypy/dist/pypy/rpython/memory/gc/test/test_direct.py Fri Oct 10 12:57:08 2008 @@ -61,8 +61,10 @@ GC_PARAMS = {} def setup_method(self, meth): + from pypy.config.pypyoption import get_pypy_config + config = get_pypy_config(translating=True).translation self.stackroots = [] - self.gc = self.GCClass(**self.GC_PARAMS) + self.gc = self.GCClass(config, **self.GC_PARAMS) self.gc.DEBUG = True self.rootwalker = DirectRootWalker(self) self.gc.set_root_walker(self.rootwalker) Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform/framework.py Fri Oct 10 12:57:08 2008 @@ -142,7 +142,7 @@ self.gcdata = gcdata self.malloc_fnptr_cache = {} - gcdata.gc = GCClass(**GC_PARAMS) + gcdata.gc = GCClass(translator.config.translation, **GC_PARAMS) root_walker = self.build_root_walker() gcdata.set_query_functions(gcdata.gc) gcdata.gc.set_root_walker(root_walker) Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Fri Oct 10 12:57:08 2008 @@ -8,7 +8,9 @@ class GCManagedHeap(object): def __init__(self, llinterp, flowgraphs, gc_class, GC_PARAMS={}): - self.gc = gc_class(chunk_size = 10, **GC_PARAMS) + translator = llinterp.typer.annotator.translator + config = translator.config.translation + self.gc = gc_class(config, chunk_size = 10, **GC_PARAMS) self.gc.set_root_walker(LLInterpRootWalker(self)) self.gc.DEBUG = True self.llinterp = llinterp From arigo at codespeak.net Fri Oct 10 13:02:02 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 13:02:02 +0200 (CEST) Subject: [pypy-svn] r58897 - in pypy/branch/builtin-profiling/pypy/interpreter: . test Message-ID: <20081010110202.6F56C169E53@codespeak.net> Author: arigo Date: Fri Oct 10 13:02:01 2008 New Revision: 58897 Modified: pypy/branch/builtin-profiling/pypy/interpreter/function.py pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py Log: (antocuni, arigo) Test and fix for an assert that can trigger. Modified: pypy/branch/builtin-profiling/pypy/interpreter/function.py ============================================================================== --- pypy/branch/builtin-profiling/pypy/interpreter/function.py (original) +++ pypy/branch/builtin-profiling/pypy/interpreter/function.py Fri Oct 10 13:02:01 2008 @@ -506,10 +506,8 @@ def is_builtin_code(w_func): from pypy.interpreter.gateway import BuiltinCode if isinstance(w_func, Method): - w_f = w_func.w_function - assert isinstance(w_f, Function) - code = w_f.getcode() - elif isinstance(w_func, Function): + w_func = w_func.w_function + if isinstance(w_func, Function): code = w_func.getcode() else: code = None Modified: pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py Fri Oct 10 13:02:01 2008 @@ -140,7 +140,37 @@ max(1, 2) bar() + sys.setprofile(None) return l """) events = space.unwrap(w_events) - assert events == ['return', 'c_call', 'c_return', 'return', 'return'] + assert events == ['return', 'c_call', 'c_return', 'return', 'c_call'] + + def test_c_call_setprofile_strange_method(self): + space = self.space + w_events = space.appexec([], """(): + import sys + class A(object): + def __init__(self, value): + self.value = value + def meth(self): + pass + MethodType = type(A.meth) + strangemeth = MethodType(A, 42, int) + l = [] + def profile(frame, event, arg): + l.append(event) + + def foo(): + sys.setprofile(profile) + + def bar(): + foo() + strangemeth() + + bar() + sys.setprofile(None) + return l + """) + events = space.unwrap(w_events) + assert events == ['return', 'call', 'return', 'return', 'c_call'] From arigo at codespeak.net Fri Oct 10 13:04:23 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 13:04:23 +0200 (CEST) Subject: [pypy-svn] r58898 - pypy/branch/builtin-profiling/pypy/interpreter/test Message-ID: <20081010110423.F1FE2169E90@codespeak.net> Author: arigo Date: Fri Oct 10 13:04:23 2008 New Revision: 58898 Modified: pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py Log: (antocuni, arigo) Added another test. Passes. Modified: pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py Fri Oct 10 13:04:23 2008 @@ -174,3 +174,22 @@ """) events = space.unwrap(w_events) assert events == ['return', 'call', 'return', 'return', 'c_call'] + + def test_c_call_profiles_immediately(self): + space = self.space + w_events = space.appexec([], """(): + import sys + l = [] + def profile(frame, event, arg): + l.append(event) + + def bar(): + sys.setprofile(profile) + max(3, 4) + + bar() + sys.setprofile(None) + return l + """) + events = space.unwrap(w_events) + assert events == ['c_call', 'c_return', 'return', 'c_call'] From iko at codespeak.net Fri Oct 10 13:11:53 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 10 Oct 2008 13:11:53 +0200 (CEST) Subject: [pypy-svn] r58899 - pypy/dist/pypy/doc/config Message-ID: <20081010111153.423F3169E99@codespeak.net> Author: iko Date: Fri Oct 10 13:11:50 2008 New Revision: 58899 Added: pypy/dist/pypy/doc/config/translation.gcconfig.debugprint.txt (contents, props changed) pypy/dist/pypy/doc/config/translation.gcconfig.txt (contents, props changed) Log: (iko, cfbolz) Document new config option Added: pypy/dist/pypy/doc/config/translation.gcconfig.debugprint.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/translation.gcconfig.debugprint.txt Fri Oct 10 13:11:50 2008 @@ -0,0 +1 @@ +If this option is set, the GC will print debugging information. Added: pypy/dist/pypy/doc/config/translation.gcconfig.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/translation.gcconfig.txt Fri Oct 10 13:11:50 2008 @@ -0,0 +1 @@ +.. intentionally empty From arigo at codespeak.net Fri Oct 10 13:21:00 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 13:21:00 +0200 (CEST) Subject: [pypy-svn] r58900 - pypy/branch/builtin-profiling/pypy/interpreter Message-ID: <20081010112100.1B1A8169E29@codespeak.net> Author: arigo Date: Fri Oct 10 13:20:59 2008 New Revision: 58900 Modified: pypy/branch/builtin-profiling/pypy/interpreter/baseobjspace.py pypy/branch/builtin-profiling/pypy/interpreter/pyopcode.py Log: (antocuni, arigo) Remove some code duplication. Modified: pypy/branch/builtin-profiling/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/builtin-profiling/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/builtin-profiling/pypy/interpreter/baseobjspace.py Fri Oct 10 13:20:59 2008 @@ -695,32 +695,16 @@ def call_valuestack(self, w_func, nargs, frame): from pypy.interpreter.function import Function, Method, is_builtin_code - if frame.is_being_profiled: - ec = self.getexecutioncontext() - is_c_call = is_builtin_code(w_func) - - # XXX: this code is copied&pasted :-( from the slow path - # below. The profiling info could be not very accurate - # because by doing this we disable fast paths when calling - # the function + if frame.is_being_profiled and is_builtin_code(w_func): + # XXX: this code is copied&pasted :-( from the slow path below + # call_valuestack(). args = frame.make_arguments(nargs) try: - try: - if is_c_call: - ec.c_call_trace(frame, w_func) - w_res = self.call_args(w_func, args) - if is_c_call: - ec.c_return_trace(frame, w_res) - return w_res - except OperationError, e: - if is_c_call: - ec.c_exception_trace(frame, e.w_value) - raise + return self.call_args_and_c_profile(frame, w_func, args) finally: if isinstance(args, ArgumentsFromValuestack): args.frame = None - if not self.config.objspace.disable_call_speedhacks: # XXX start of hack for performance hint(w_func.__class__, promote=True) @@ -746,6 +730,17 @@ if isinstance(args, ArgumentsFromValuestack): args.frame = None + def call_args_and_c_profile(self, frame, w_func, args): + ec = self.getexecutioncontext() + ec.c_call_trace(frame, w_func) + try: + w_res = self.call_args(w_func, args) + except OperationError, e: + ec.c_exception_trace(frame, e.w_value) + raise + ec.c_return_trace(frame, w_res) + return w_res + 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) Modified: pypy/branch/builtin-profiling/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/builtin-profiling/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/builtin-profiling/pypy/interpreter/pyopcode.py Fri Oct 10 13:20:59 2008 @@ -867,18 +867,7 @@ args = Arguments(f.space, arguments, keywords, w_star, w_starstar) w_function = f.popvalue() if f.is_being_profiled and is_builtin_code(w_function): - is_c_call = is_builtin_code(w_function) - ec = f.space.getexecutioncontext() - if is_c_call: - ec.c_call_trace(f, w_function) - try: - w_result = f.space.call_args(w_function, args) - except OperationError, e: - if is_c_call: - ec.c_exception_trace(f, e.w_value) - raise - if is_c_call: - ec.c_return_trace(f, w_function) + w_result = f.space.call_args_and_c_profile(f, w_function, args) else: w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) From antocuni at codespeak.net Fri Oct 10 13:24:54 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 10 Oct 2008 13:24:54 +0200 (CEST) Subject: [pypy-svn] r58901 - pypy/branch/builtin-profiling/pypy/interpreter Message-ID: <20081010112454.0AA74169E4A@codespeak.net> Author: antocuni Date: Fri Oct 10 13:24:54 2008 New Revision: 58901 Modified: pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py Log: (antocuni, arigo) wrap line Modified: pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py Fri Oct 10 13:24:54 2008 @@ -246,7 +246,8 @@ # Profile cases if self.profilefunc is not None: - if event not in ['leaveframe', 'call', 'c_call', 'c_return', 'c_exception']: + if event not in ['leaveframe', 'call', 'c_call', + 'c_return', 'c_exception']: return last_exception = None From arigo at codespeak.net Fri Oct 10 13:25:15 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 13:25:15 +0200 (CEST) Subject: [pypy-svn] r58902 - pypy/branch/builtin-profiling/pypy/interpreter Message-ID: <20081010112515.4CDA8169E4A@codespeak.net> Author: arigo Date: Fri Oct 10 13:25:14 2008 New Revision: 58902 Modified: pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py Log: (antocuni, arigo) Unstrangify. Modified: pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py Fri Oct 10 13:25:14 2008 @@ -216,7 +216,7 @@ space = self.space # Tracing cases - if event in ['call']: + if event == 'call': w_callback = self.w_tracefunc else: w_callback = frame.w_f_trace From antocuni at codespeak.net Fri Oct 10 13:27:26 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 10 Oct 2008 13:27:26 +0200 (CEST) Subject: [pypy-svn] r58903 - pypy/branch/builtin-profiling/pypy/interpreter Message-ID: <20081010112726.19C91169E4A@codespeak.net> Author: antocuni Date: Fri Oct 10 13:27:25 2008 New Revision: 58903 Modified: pypy/branch/builtin-profiling/pypy/interpreter/gateway.py Log: (antocuni, arigo) revert gateway to the state it was before the branch Modified: pypy/branch/builtin-profiling/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/builtin-profiling/pypy/interpreter/gateway.py (original) +++ pypy/branch/builtin-profiling/pypy/interpreter/gateway.py Fri Oct 10 13:27:25 2008 @@ -378,16 +378,6 @@ else: return typ.__name__ + '_w' -def getexecutioncontext_and_frame(space): - ctx = space.getexecutioncontext() - if not ctx.framestack.empty(): - frame = ctx.framestack.top() - else: - ctx = None - frame = None - return ctx, frame - - class BuiltinCode(eval.Code): "The code object implementing a built-in (interpreter-level) hook." _immutable_ = True @@ -490,15 +480,10 @@ def funcrun(self, func, args): space = func.space - #ctx, frame = getexecutioncontext_and_frame(space) activation = self.activation scope_w = args.parse(func.name, self.sig, func.defs_w) try: - #if frame: - # ctx.c_call_trace(frame, activation._run) w_result = activation._run(space, scope_w) - #if frame: - # ctx.c_return_trace(frame, w_result) except KeyboardInterrupt: raise OperationError(space.w_KeyboardInterrupt, space.w_None) @@ -524,13 +509,8 @@ def funcrun(self, func, args): space = func.space - #ctx, frame = getexecutioncontext_and_frame(space) try: - #if frame: - # ctx.c_call_trace(frame, self.func__args__) w_result = self.func__args__(space, args) - #if frame: - # ctx.c_return_trace(frame, w_result) except KeyboardInterrupt: raise OperationError(space.w_KeyboardInterrupt, space.w_None) except MemoryError: @@ -553,18 +533,13 @@ def funcrun(self, func, args): space = func.space - #ctx, frame = getexecutioncontext_and_frame(space) try: w_obj, newargs = args.popfirst() except IndexError: return BuiltinCode.funcrun(self, func, args) else: try: - #if frame: - # ctx.c_call_trace(frame, self.func__args__) w_result = self.func__args__(space, w_obj, newargs) - #if frame: - # ctx.c_return_trace(frame, w_result) except KeyboardInterrupt: raise OperationError(space.w_KeyboardInterrupt, space.w_None) except MemoryError: @@ -587,12 +562,7 @@ def fastcall_0(self, space, w_func): self = hint(self, deepfreeze=True) try: - #ctx, frame = getexecutioncontext_and_frame(space) - #if frame: - # ctx.c_call_trace(frame, self.fastfunc_0) w_result = self.fastfunc_0(space) - #if frame: - # ctx.c_return_trace(frame, w_result) except KeyboardInterrupt: raise OperationError(space.w_KeyboardInterrupt, space.w_None) except MemoryError: @@ -608,12 +578,7 @@ def fastcall_1(self, space, w_func, w1): self = hint(self, deepfreeze=True) try: - #ctx, frame = getexecutioncontext_and_frame(space) - #if frame: - # ctx.c_call_trace(frame, self.fastfunc_1) w_result = self.fastfunc_1(space, w1) - #if frame: - # ctx.c_return_trace(frame, w_result) except KeyboardInterrupt: raise OperationError(space.w_KeyboardInterrupt, space.w_None) except MemoryError: @@ -636,12 +601,7 @@ def fastcall_2(self, space, w_func, w1, w2): self = hint(self, deepfreeze=True) try: - #ctx, frame = getexecutioncontext_and_frame(space) - #if frame: - # ctx.c_call_trace(frame, self.fastfunc_2) w_result = self.fastfunc_2(space, w1, w2) - #if frame: - # ctx.c_return_trace(frame, w_result) except KeyboardInterrupt: raise OperationError(space.w_KeyboardInterrupt, space.w_None) except MemoryError: @@ -661,15 +621,10 @@ return w_result class BuiltinCode3(BuiltinCode): - def fastcall_3(self, space, w_func, w1, w2, w3): + def fastcall_3(self, space, func, w1, w2, w3): self = hint(self, deepfreeze=True) try: - #ctx, frame = getexecutioncontext_and_frame(space) - #if frame: - # ctx.c_call_trace(frame, self.fastfunc_3) w_result = self.fastfunc_3(space, w1, w2, w3) - #if frame: - # ctx.c_return_trace(frame, w_result) except KeyboardInterrupt: raise OperationError(space.w_KeyboardInterrupt, space.w_None) except MemoryError: @@ -689,15 +644,10 @@ return w_result class BuiltinCode4(BuiltinCode): - def fastcall_4(self, space, w_func, w1, w2, w3, w4): + def fastcall_4(self, space, func, w1, w2, w3, w4): self = hint(self, deepfreeze=True) - #ctx, frame = getexecutioncontext_and_frame(space) try: - #if frame: - #ctx.c_call_trace(frame, self.fastfunc_4) w_result = self.fastfunc_4(space, w1, w2, w3, w4) - #if frame: - # ctx.c_return_trace(frame, w_result) except KeyboardInterrupt: raise OperationError(space.w_KeyboardInterrupt, space.w_None) except MemoryError: From arigo at codespeak.net Fri Oct 10 14:49:24 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 14:49:24 +0200 (CEST) Subject: [pypy-svn] r58904 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081010124924.26E2516A0B3@codespeak.net> Author: arigo Date: Fri Oct 10 14:49:23 2008 New Revision: 58904 Added: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_extcall.py - copied, changed from r58903, pypy/branch/2.5-merge/lib-python/2.5.2/test/test_extcall.py Log: (antocuni, arigo) Don't depend on dictionary order in an output test. Copied: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_extcall.py (from r58903, pypy/branch/2.5-merge/lib-python/2.5.2/test/test_extcall.py) ============================================================================== --- pypy/branch/2.5-merge/lib-python/2.5.2/test/test_extcall.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_extcall.py Fri Oct 10 14:49:23 2008 @@ -140,7 +140,10 @@ try: g(1, 2, 3, a=4, b=5, *(6, 7), **{'a':8, 'b':9}) except TypeError, err: - print err + # The error message could mention either 'a' or 'b', as both are + # provided twice. We enforce a consistent output... + msg = str(err) + print msg.replace("'a'", "'b'") else: print "should raise TypeError: keyword parameter redefined" From arigo at codespeak.net Fri Oct 10 14:50:53 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 14:50:53 +0200 (CEST) Subject: [pypy-svn] r58905 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/output Message-ID: <20081010125053.A827116A0B5@codespeak.net> Author: arigo Date: Fri Oct 10 14:50:52 2008 New Revision: 58905 Added: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/output/test_extcall Log: (antocuni, arigo) Regenerate the output that we get on top of PyPy. There are various differences, but our error messages make just as much sense as CPython's (except in one case where they make *more* sense). Added: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/output/test_extcall ============================================================================== --- (empty file) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/output/test_extcall Fri Oct 10 14:50:52 2008 @@ -0,0 +1,112 @@ +test_extcall +() {} +(1,) {} +(1, 2) {} +(1, 2, 3) {} +(1, 2, 3, 4, 5) {} +(1, 2, 3, 4, 5) {} +(1, 2, 3, 4, 5) {} +(1, 2, 3) {'a': 4, 'b': 5} +(1, 2, 3, 4, 5) {'a': 6, 'b': 7} +(1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} +TypeError: g() takes at least 1 argument (0 given) +TypeError: g() takes at least 1 argument (0 given) +TypeError: g() takes at least 1 argument (0 given) +1 () {} +1 (2,) {} +1 (2, 3) {} +1 (2, 3, 4, 5) {} +0 (1, 2) {} +0 (1, 2, 3) {} +1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4} +{'a': 1, 'b': 2, 'c': 3} +{'a': 1, 'b': 2, 'c': 3} +g() got multiple values for keyword argument 'x' +got multiple values for keyword argument 'b' +keywords must be strings +h() got an unexpected keyword argument 'e' +iteration over non-sequence +iteration over non-sequence +object None is not callable +argument after ** must be a dictionary +argument after ** must be a dictionary +object None is not callable +got multiple values for keyword argument 'b' +3 512 True +3 +3 +za () {} -> za() takes exactly 1 argument (0 given) +za () {'a': 'aa'} -> ok za aa B D E V a +za () {'d': 'dd'} -> za() got an unexpected keyword argument 'd' +za () {'a': 'aa', 'd': 'dd'} -> za() got an unexpected keyword argument 'd' +za () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got 3 unexpected keyword arguments +za (1, 2) {} -> za() takes exactly 1 argument (2 given) +za (1, 2) {'a': 'aa'} -> za() got multiple values for keyword argument 'a' +za (1, 2) {'d': 'dd'} -> za() takes exactly 1 argument (3 given) +za (1, 2) {'a': 'aa', 'd': 'dd'} -> za() got multiple values for keyword argument 'a' +za (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got multiple values for keyword argument 'a' +za (1, 2, 3, 4, 5) {} -> za() takes exactly 1 argument (5 given) +za (1, 2, 3, 4, 5) {'a': 'aa'} -> za() got multiple values for keyword argument 'a' +za (1, 2, 3, 4, 5) {'d': 'dd'} -> za() takes exactly 1 argument (6 given) +za (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> za() got multiple values for keyword argument 'a' +za (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got multiple values for keyword argument 'a' +zade () {} -> zade() takes at least 1 argument (0 given) +zade () {'a': 'aa'} -> ok zade aa B d e V a +zade () {'d': 'dd'} -> zade() takes at least 1 non-keyword argument (0 given) +zade () {'a': 'aa', 'd': 'dd'} -> ok zade aa B dd e V d +zade () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got an unexpected keyword argument 'b' +zade (1, 2) {} -> ok zade 1 B 2 e V e +zade (1, 2) {'a': 'aa'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2) {'d': 'dd'} -> zade() got multiple values for keyword argument 'd' +zade (1, 2) {'a': 'aa', 'd': 'dd'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2, 3, 4, 5) {} -> zade() takes at most 3 arguments (5 given) +zade (1, 2, 3, 4, 5) {'a': 'aa'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2, 3, 4, 5) {'d': 'dd'} -> zade() got multiple values for keyword argument 'd' +zade (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got multiple values for keyword argument 'a' +zabk () {} -> zabk() takes exactly 2 non-keyword arguments (0 given) +zabk () {'a': 'aa'} -> zabk() takes exactly 2 non-keyword arguments (1 given) +zabk () {'d': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (0 given) +zabk () {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (1 given) +zabk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabk aa bb D E V {'d': 'dd', 'e': 'ee'} +zabk (1, 2) {} -> ok zabk 1 2 D E V {} +zabk (1, 2) {'a': 'aa'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2) {'d': 'dd'} -> ok zabk 1 2 D E V {'d': 'dd'} +zabk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2, 3, 4, 5) {} -> zabk() takes exactly 2 non-keyword arguments (5 given) +zabk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (5 given) +zabk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() got multiple values for keyword argument 'a' +zabdv () {} -> zabdv() takes at least 2 arguments (0 given) +zabdv () {'a': 'aa'} -> zabdv() takes at least 2 non-keyword arguments (1 given) +zabdv () {'d': 'dd'} -> zabdv() takes at least 2 non-keyword arguments (0 given) +zabdv () {'a': 'aa', 'd': 'dd'} -> zabdv() takes at least 2 non-keyword arguments (1 given) +zabdv () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got an unexpected keyword argument 'e' +zabdv (1, 2) {} -> ok zabdv 1 2 d E () e +zabdv (1, 2) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2) {'d': 'dd'} -> ok zabdv 1 2 dd E () d +zabdv (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2, 3, 4, 5) {} -> ok zabdv 1 2 3 E (4, 5) e +zabdv (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdv() got multiple values for keyword argument 'd' +zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a' +zabdevk () {} -> zabdevk() takes at least 2 arguments (0 given) +zabdevk () {'a': 'aa'} -> zabdevk() takes at least 2 non-keyword arguments (1 given) +zabdevk () {'d': 'dd'} -> zabdevk() takes at least 2 non-keyword arguments (0 given) +zabdevk () {'a': 'aa', 'd': 'dd'} -> zabdevk() takes at least 2 non-keyword arguments (1 given) +zabdevk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabdevk aa bb dd ee () {} +zabdevk (1, 2) {} -> ok zabdevk 1 2 d e () {} +zabdevk (1, 2) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2) {'d': 'dd'} -> ok zabdevk 1 2 dd e () {} +zabdevk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2, 3, 4, 5) {} -> ok zabdevk 1 2 3 4 (5,) {} +zabdevk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdevk() got multiple values for keyword argument 'd' +zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a' From fijal at codespeak.net Fri Oct 10 14:57:48 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 14:57:48 +0200 (CEST) Subject: [pypy-svn] r58906 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test Message-ID: <20081010125748.AA501169FCF@codespeak.net> Author: fijal Date: Fri Oct 10 14:57:48 2008 New Revision: 58906 Added: pypy/branch/cbuild-refactor/pypy/translator/platform/ (props changed) pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (contents, props changed) pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (contents, props changed) pypy/branch/cbuild-refactor/pypy/translator/platform/test/ (props changed) pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py (contents, props changed) Log: (fijal, pedronis) Starting target platform abstraction. Added: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Fri Oct 10 14:57:48 2008 @@ -0,0 +1,36 @@ + +""" Platform object that allows you to compile/execute C sources for given +platform. +""" + +import sys + +class CompilationError(Exception): + def __init__(self, out, err): + self.out = out + self.err = err + +class ExecutionResult(object): + def __init__(self, returncode, out, err): + self.returncode = returncode + self.out = out + self.err = err + +class Platform(object): + def __init__(self, cc): + self.cc = cc + + def compile(self, cfiles, eci): + raise NotImplementedError("Pure abstract baseclass") + + def execute(self, file_to_exec): + raise NotImplementedError("Pure abstract baseclass") + + def __repr__(self): + return '<%s cc=%s>' % (self.__class__.__name__, self.cc) + +if sys.platform == 'linux2': + from pypy.translator.platform.linux import Linux + host = Linux() +else: + xxx Added: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Fri Oct 10 14:57:48 2008 @@ -0,0 +1,29 @@ + +import py +from pypy.translator.platform import Platform, CompilationError, ExecutionResult +from subprocess import PIPE, Popen + +def _run_subprocess(args): + pipe = Popen(args, executable=args[0], + stdout=PIPE, stderr=PIPE, shell=False) + stdout, stderr = pipe.communicate() + return pipe.returncode, stdout, stderr + +class Linux(Platform): + def __init__(self, cc='gcc'): + self.cc = cc + + def compile(self, cfiles, eci): + cfiles = [py.path.local(f) for f in cfiles] + # XXX ignore eci + args = [self.cc] + [str(f) for f in cfiles] + exe_name = cfiles[0].dirpath().join(cfiles[0].purebasename) + args += ['-o', str(exe_name)] + returncode, stdout, stderr = _run_subprocess(args) + if returncode != 0: + raise CompilationError(stdout, stderr) + return exe_name + + def execute(self, executable): + returncode, stdout, stderr = _run_subprocess([str(executable)]) + return ExecutionResult(returncode, stdout, stderr) Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Fri Oct 10 14:57:48 2008 @@ -0,0 +1,19 @@ + +from pypy.tool.udir import udir +from pypy.translator.platform import host + +def test_simple_enough(): + cfile = udir.join('test_simple_enough.c') + tmpdir = cfile.write(''' + #include + int main() + { + printf("42\\n"); + return 0; + } + ''') + executable = host.compile([cfile], None) + res = host.execute(executable) + assert res.out == '42\n' + assert res.err == '' + assert res.returncode == 0 From fijal at codespeak.net Fri Oct 10 15:28:41 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 15:28:41 +0200 (CEST) Subject: [pypy-svn] r58907 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test Message-ID: <20081010132841.1E69316A038@codespeak.net> Author: fijal Date: Fri Oct 10 15:28:39 2008 New Revision: 58907 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Log: (pedronis, fijal) Nice error messages Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Fri Oct 10 15:28:39 2008 @@ -3,6 +3,11 @@ from pypy.translator.platform import Platform, CompilationError, ExecutionResult from subprocess import PIPE, Popen +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("cbuild") +py.log.setconsumer("cbuild", ansi_log) + def _run_subprocess(args): pipe = Popen(args, executable=args[0], stdout=PIPE, stderr=PIPE, shell=False) @@ -19,8 +24,16 @@ args = [self.cc] + [str(f) for f in cfiles] exe_name = cfiles[0].dirpath().join(cfiles[0].purebasename) args += ['-o', str(exe_name)] + log.execute(' '.join(args)) returncode, stdout, stderr = _run_subprocess(args) if returncode != 0: + errorfile = exe_name.new(ext='errors') + errorfile.write(stderr) + stderrlines = stderr.splitlines() + for line in stderrlines[:5]: + log.ERROR(line) + if len(stderrlines) > 5: + log.ERROR('...') raise CompilationError(stdout, stderr) return exe_name Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Fri Oct 10 15:28:39 2008 @@ -1,10 +1,11 @@ +import py from pypy.tool.udir import udir -from pypy.translator.platform import host +from pypy.translator.platform import host, CompilationError def test_simple_enough(): cfile = udir.join('test_simple_enough.c') - tmpdir = cfile.write(''' + cfile.write(''' #include int main() { @@ -17,3 +18,15 @@ assert res.out == '42\n' assert res.err == '' assert res.returncode == 0 + +def test_nice_errors(): + cfile = udir.join('test_nice_errors.c') + cfile.write('') + try: + executable = host.compile([cfile], None) + except CompilationError, e: + filename = cfile.dirpath().join(cfile.purebasename + '.errors') + assert filename.read() == e.err + else: + py.test.fail("Did not raise") + From fijal at codespeak.net Fri Oct 10 15:42:00 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 15:42:00 +0200 (CEST) Subject: [pypy-svn] r58908 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test Message-ID: <20081010134200.78B3016A0F9@codespeak.net> Author: fijal Date: Fri Oct 10 15:41:59 2008 New Revision: 58908 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Log: (pedronis, fijal) Start supporting eci Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Fri Oct 10 15:41:59 2008 @@ -18,10 +18,16 @@ def __init__(self, cc='gcc'): self.cc = cc + def _args_from_eci(self, cc, cfiles, eci): + include_dirs = ['-I%s' % (idir,) for idir in eci.include_dirs] + library_dirs = ['-L%s' % (ldir,) for ldir in eci.library_dirs] + libraries = ['-l%s' % (lib,) for lib in eci.libraries] + return ([self.cc] + include_dirs + [str(f) for f in cfiles] + + library_dirs + libraries) + def compile(self, cfiles, eci): cfiles = [py.path.local(f) for f in cfiles] - # XXX ignore eci - args = [self.cc] + [str(f) for f in cfiles] + args = self._args_from_eci(self.cc, cfiles, eci) exe_name = cfiles[0].dirpath().join(cfiles[0].purebasename) args += ['-o', str(exe_name)] log.execute(' '.join(args)) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Fri Oct 10 15:41:59 2008 @@ -2,6 +2,7 @@ import py from pypy.tool.udir import udir from pypy.translator.platform import host, CompilationError +from pypy.translator.tool.cbuild import ExternalCompilationInfo def test_simple_enough(): cfile = udir.join('test_simple_enough.c') @@ -13,7 +14,7 @@ return 0; } ''') - executable = host.compile([cfile], None) + executable = host.compile([cfile], ExternalCompilationInfo()) res = host.execute(executable) assert res.out == '42\n' assert res.err == '' @@ -23,10 +24,30 @@ cfile = udir.join('test_nice_errors.c') cfile.write('') try: - executable = host.compile([cfile], None) + executable = host.compile([cfile], ExternalCompilationInfo()) except CompilationError, e: filename = cfile.dirpath().join(cfile.purebasename + '.errors') assert filename.read() == e.err else: py.test.fail("Did not raise") +def test_use_eci(): + tmpdir = udir.join('use_eci').ensure(dir=1) + hfile = tmpdir.join('needed.h') + hfile.write('#define SOMEHASHDEFINE 42\n') + eci = ExternalCompilationInfo(include_dirs=[tmpdir]) + cfile = udir.join('use_eci_c.c') + cfile.write(''' + #include + #include "needed.h" + int main() + { + printf("%d\\n", SOMEHASHDEFINE); + return 0; + } + ''') + executable = host.compile([cfile], eci) + res = host.execute(executable) + assert res.out == '42\n' + assert res.err == '' + assert res.returncode == 0 From fijal at codespeak.net Fri Oct 10 16:01:05 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 16:01:05 +0200 (CEST) Subject: [pypy-svn] r58909 - in pypy/branch/cbuild-refactor/pypy/translator: platform platform/test tool tool/test Message-ID: <20081010140105.7098A16A075@codespeak.net> Author: fijal Date: Fri Oct 10 16:01:04 2008 New Revision: 58909 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py Log: (fijal, pedronis) Gradually move from cbuild to platform Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Fri Oct 10 16:01:04 2008 @@ -20,7 +20,7 @@ def __init__(self, cc): self.cc = cc - def compile(self, cfiles, eci): + def compile(self, cfiles, eci, outputfilename=None, standalone=True): raise NotImplementedError("Pure abstract baseclass") def execute(self, file_to_exec): Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Fri Oct 10 16:01:04 2008 @@ -1,9 +1,8 @@ -import py +import py, os from pypy.translator.platform import Platform, CompilationError, ExecutionResult from subprocess import PIPE, Popen -import py from pypy.tool.ansi_print import ansi_log log = py.log.Producer("cbuild") py.log.setconsumer("cbuild", ansi_log) @@ -18,18 +17,30 @@ def __init__(self, cc='gcc'): self.cc = cc - def _args_from_eci(self, cc, cfiles, eci): + def _args_from_eci(self, cfiles, eci): include_dirs = ['-I%s' % (idir,) for idir in eci.include_dirs] library_dirs = ['-L%s' % (ldir,) for ldir in eci.library_dirs] libraries = ['-l%s' % (lib,) for lib in eci.libraries] - return ([self.cc] + include_dirs + [str(f) for f in cfiles] + + return (include_dirs + [str(f) for f in cfiles] + library_dirs + libraries) - def compile(self, cfiles, eci): + def _args_for_shared(self, args): + return ['-shared'] + args + + def compile(self, cfiles, eci, outputfilename=None, standalone=True): cfiles = [py.path.local(f) for f in cfiles] - args = self._args_from_eci(self.cc, cfiles, eci) - exe_name = cfiles[0].dirpath().join(cfiles[0].purebasename) + cfiles += [py.path.local(f) for f in eci.separate_module_files] + args = self._args_from_eci(cfiles, eci) + if outputfilename is None: + outputfilename = cfiles[0].purebasename + exe_name = py.path.local(os.path.join(str(cfiles[0].dirpath()), + outputfilename)) + if not standalone: + exe_name += '.so' args += ['-o', str(exe_name)] + if not standalone: + args = self._args_for_shared(args) + args = [self.cc] + args log.execute(' '.join(args)) returncode, stdout, stderr = _run_subprocess(args) if returncode != 0: Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Fri Oct 10 16:01:04 2008 @@ -1,5 +1,5 @@ -import py +import py, sys from pypy.tool.udir import udir from pypy.translator.platform import host, CompilationError from pypy.translator.tool.cbuild import ExternalCompilationInfo @@ -51,3 +51,24 @@ assert res.out == '42\n' assert res.err == '' assert res.returncode == 0 + +def test_standalone_library(): + tmpdir = udir.join('standalone_library').ensure(dir=1) + c_file = tmpdir.join('stand1.c') + c_file.write(''' + #include + #include + + int main() + { + printf("%f\\n", pow(2.0, 2.0)); + }''') + if sys.platform != 'win32': + eci = ExternalCompilationInfo( + libraries = ['m'], + ) + else: + eci = ExternalCompilationInfo() + executable = host.compile([c_file], eci) + res = host.execute(executable) + assert res.out.startswith('4.0') Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Fri Oct 10 16:01:04 2008 @@ -3,6 +3,7 @@ import os, sys, inspect, re, imp from pypy.translator.tool import stdoutcapture from pypy.tool.autopath import pypydir +from pypy.translator.platform import host import py from pypy.tool.ansi_print import ansi_log @@ -259,7 +260,8 @@ self = self.convert_sources_to_files() if not self.separate_module_files: return self - lib = compile_c_module([], 'externmod', self) + lib = str(host.compile([], self, outputfilename='externmod', + standalone=False)) d = self._copy_attributes() d['libraries'] += (lib,) d['separate_module_files'] = () Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py Fri Oct 10 16:01:04 2008 @@ -6,22 +6,6 @@ from subprocess import Popen, PIPE, STDOUT from pypy.rlib.pyplatform import Maemo -def test_simple_executable(): - print udir - testpath = udir.join('testbuildexec') - t = testpath.ensure("test.c") - t.write(r""" - #include - int main() { - printf("hello world\n"); - return 0; - } -""") - eci = ExternalCompilationInfo() - testexec = build_executable([t], eci) - out = py.process.cmdexec(testexec) - assert out.startswith('hello world') - class TestEci: def setup_class(cls): tmpdir = udir.ensure('testeci', dir=1) @@ -34,28 +18,6 @@ ''')) cls.modfile = c_file cls.tmpdir = tmpdir - - def test_standalone(self): - tmpdir = self.tmpdir - c_file = tmpdir.join('stand1.c') - c_file.write(''' - #include - #include - - int main() - { - printf("%f\\n", pow(2.0, 2.0)); - }''') - if sys.platform != 'win32': - eci = ExternalCompilationInfo( - libraries = ['m'], - ) - else: - eci = ExternalCompilationInfo() - output = build_executable([c_file], eci) - p = Popen(output, stdout=PIPE, stderr=STDOUT) - p.wait() - assert p.stdout.readline().startswith('4.0') def test_merge(self): e1 = ExternalCompilationInfo( @@ -158,6 +120,11 @@ ExternalCompilationInfo.from_config_tool, 'dxowqbncpqympqhe-config') + + + + +class Stuff: def test_platform(self): from pypy.rlib.pyplatform import Platform class Expected(Exception): From fijal at codespeak.net Fri Oct 10 16:18:14 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 16:18:14 +0200 (CEST) Subject: [pypy-svn] r58910 - in pypy/branch/cbuild-refactor/pypy/translator: . c platform tool Message-ID: <20081010141814.58C51169F44@codespeak.net> Author: fijal Date: Fri Oct 10 16:18:11 2008 New Revision: 58910 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py pypy/branch/cbuild-refactor/pypy/translator/translator.py Log: (fijal, pedronis) Start to make genc use platform Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Fri Oct 10 16:18:11 2008 @@ -32,7 +32,15 @@ self.gcpolicy = gcpolicy # for tests only, e.g. rpython/memory/ if gcpolicy is not None and gcpolicy.requires_stackless: config.translation.stackless = True - self.eci = ExternalCompilationInfo() + self.eci = self.get_eci() + + def get_eci(self): + from distutils import sysconfig + python_inc = sysconfig.get_python_inc() + pypy_include_dir = py.path.local(autopath.pypydir).join('translator', 'c') + return ExternalCompilationInfo( + include_dirs=[python_inc, pypy_include_dir] + ) def build_database(self): translator = self.translator @@ -206,9 +214,8 @@ export_symbols.append('malloc_counters') extsymeci = ExternalCompilationInfo(export_symbols=export_symbols) self.eci = self.eci.merge(extsymeci) - compile_c_module([self.c_source_filename] + self.extrafiles, - self.c_source_filename.purebasename, self.eci, - tmpdir=self.c_source_filename.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): Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Fri Oct 10 16:18:11 2008 @@ -14,6 +14,8 @@ return pipe.returncode, stdout, stderr class Linux(Platform): + link_extra = ['-lpthread'] + def __init__(self, cc='gcc'): self.cc = cc @@ -22,7 +24,7 @@ library_dirs = ['-L%s' % (ldir,) for ldir in eci.library_dirs] libraries = ['-l%s' % (lib,) for lib in eci.libraries] return (include_dirs + [str(f) for f in cfiles] + - library_dirs + libraries) + library_dirs + libraries + self.link_extra) def _args_for_shared(self, args): return ['-shared'] + args Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Fri Oct 10 16:18:11 2008 @@ -378,13 +378,6 @@ def __init__(self, cfilenames, eci, outputfilename=None, compiler_exe=None, profbased=None, standalone=True): - from distutils import sysconfig - python_inc = sysconfig.get_python_inc() - pypy_include_dir = py.path.local(autopath.pypydir).join('translator', 'c') - eci = eci.merge(ExternalCompilationInfo( - include_dirs=[python_inc, pypy_include_dir], - platform=eci.platform, - )) self.cfilenames = cfilenames if standalone: ext = '' Modified: pypy/branch/cbuild-refactor/pypy/translator/translator.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/translator.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/translator.py Fri Oct 10 16:18:11 2008 @@ -13,6 +13,7 @@ from pypy.tool.sourcetools import nice_repr_for_func from pypy.config.pypyoption import pypy_optiondescription from pypy.config.translationoption import get_combined_translation_config +from pypy.config.translationoption import get_platform import py log = py.log.Producer("flowgraph") py.log.setconsumer("flowgraph", ansi_log) @@ -36,6 +37,7 @@ if attr in flowing_flags: setattr(config.translation, attr, flowing_flags[attr]) self.config = config + self.platform = get_platform(config) self.create_flowspace_config() self.annotator = None self.rtyper = None From fijal at codespeak.net Fri Oct 10 16:21:26 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 16:21:26 +0200 (CEST) Subject: [pypy-svn] r58911 - pypy/branch/cbuild-refactor/pypy/translator/c/test Message-ID: <20081010142126.B3D0016A011@codespeak.net> Author: fijal Date: Fri Oct 10 16:21:26 2008 New Revision: 58911 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_extfunc.py Log: Remove outdated tests, unskip working one Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_extfunc.py Fri Oct 10 16:21:26 2008 @@ -382,97 +382,6 @@ res = f(1.5) assert eval(res) == 1.5 -def test_lock(): - py.test.skip("XXX out-of-date, and should not be here") - import thread - import pypy.module.thread.rpython.exttable # for declare()/declaretype() - def fn(): - l = thread.allocate_lock() - ok1 = l.acquire(True) - ok2 = l.acquire(False) - l.release() - ok2_and_a_half = False - try: - l.release() - except thread.error: - ok2_and_a_half = True - ok3 = l.acquire(False) - return ok1 and not ok2 and ok2_and_a_half and ok3 - f = compile(fn, []) - res = f() - assert res is True - -def test_simple_start_new_thread(): - py.test.skip("XXX out-of-date, and should not be here") - import thread - import pypy.module.thread.rpython.exttable # for declare()/declaretype() - class Arg: - pass - def mythreadedfunction(arg): - assert arg.value == 42 - def myotherthreadedfunction(arg): - assert arg.value == 43 - a42 = Arg() - a42.value = 42 - a43 = Arg() - a43.value = 43 - def fn(i): - thread.start_new_thread(mythreadedfunction, (a42,)) - thread.start_new_thread(myotherthreadedfunction, (a43,)) - if i == 1: - x = mythreadedfunction - a = a42 - else: - x = myotherthreadedfunction - a = a43 - thread.start_new_thread(x, (a,)) - return 42 - f = compile(fn, [int]) - res = f(1) - assert res == 42 - -def test_start_new_thread(): - py.test.skip("XXX out-of-date, and should not be here") - import thread - import pypy.module.thread.rpython.exttable # for declare()/declaretype() - class Arg: - pass - a = Arg() - a.x = 5 - a.lock = thread.allocate_lock() - def mythreadedfunction(arg): - arg.x += 37 - arg.myident = thread.get_ident() - arg.lock.release() - def fn(): - a.lock.acquire(True) - ident = thread.start_new_thread(mythreadedfunction, (a,)) - assert ident != thread.get_ident() - a.lock.acquire(True) # wait for the thread to finish - assert a.myident == ident - return a.x - f = compile(fn, []) - res = f() - assert res == 42 - -def test_prebuilt_lock(): - py.test.skip("XXX out-of-date, and should not be here") - import thread - import pypy.module.thread.rpython.exttable # for declare()/declaretype() - lock0 = thread.allocate_lock() - lock1 = thread.allocate_lock() - lock1.acquire() - def fn(i): - lock = [lock0, lock1][i] - ok = lock.acquire(False) - if ok: lock.release() - return ok - f = compile(fn, [int]) - res = f(0) - assert res is True - res = f(1) - assert res is False - def test_os_unlink(): tmpfile = str(udir.join('test_os_path_exists.TMP')) def fn(): @@ -845,10 +754,9 @@ py.test.raises(OSError, "func()") def test_execve(): - import py; py.test.skip("in-progress") filename = str(udir.join('test_execve.txt')) + progname = sys.executable def does_stuff(): - progname = str(sys.executable) l = [] l.append(progname) l.append("-c") From iko at codespeak.net Fri Oct 10 16:33:44 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 10 Oct 2008 16:33:44 +0200 (CEST) Subject: [pypy-svn] r58912 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081010143344.D3FB316A12A@codespeak.net> Author: iko Date: Fri Oct 10 16:33:44 2008 New Revision: 58912 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py Log: Fix typos Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_support.py Fri Oct 10 16:33:44 2008 @@ -539,7 +539,7 @@ def impl_detail(f): """A decorator to skip a whole function if not running on top of CPython. """ - if check_impl_details: + if check_impl_detail: return f else: def _skip_check_impl_detail(*args, **kwds): @@ -547,7 +547,7 @@ sys.stderr.write("Skipping %s checking CPython-specific " "implementation details\n" % (f.__name__,)) return - return skip_check_impl_detail + return _skip_check_impl_detail def gc_collect(): """Force as many objects as possible to be collected. From iko at codespeak.net Fri Oct 10 16:34:53 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 10 Oct 2008 16:34:53 +0200 (CEST) Subject: [pypy-svn] r58913 - in pypy/branch/2.5-merge: lib-python/modified-2.5.2/test pypy/module/_weakref Message-ID: <20081010143453.DFE61169E90@codespeak.net> Author: iko Date: Fri Oct 10 16:34:52 2008 New Revision: 58913 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_weakref.py pypy/branch/2.5-merge/pypy/module/_weakref/interp__weakref.py Log: (iko, cfbolz) Clean up test_weakref and exclude some more implementation details Allow weakref.ref subclasses to have additional arguments to __init__ (fixes failing doctest) Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_weakref.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_weakref.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_weakref.py Fri Oct 10 16:34:52 2008 @@ -69,9 +69,7 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del o - gc.collect() - gc.collect() - gc.collect() + test_support.gc_collect() self.assert_(ref1() is None, "expected reference to be invalidated") self.assert_(ref2() is None, @@ -103,17 +101,16 @@ ref1 = weakref.proxy(o, self.callback) ref2 = weakref.proxy(o, self.callback) del o - gc.collect() - gc.collect() - gc.collect() + test_support.gc_collect() def check(proxy): proxy.bar self.assertRaises(weakref.ReferenceError, check, ref1) self.assertRaises(weakref.ReferenceError, check, ref2) - # Works only with refcounting - # self.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C())) + if test_support.check_impl_detail: + # Works only with refcounting + self.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C())) self.assert_(self.cbcalled == 2) def check_basic_ref(self, factory): @@ -130,9 +127,7 @@ o = factory() ref = weakref.ref(o, self.callback) del o - gc.collect() - gc.collect() - gc.collect() + test_support.gc_collect() self.assert_(self.cbcalled == 1, "callback did not properly set 'cbcalled'") @@ -158,7 +153,7 @@ self.assert_(weakref.getweakrefcount(o) == 2, "wrong weak ref count for object") del proxy - gc.collect() + test_support.gc_collect() self.assert_(weakref.getweakrefcount(o) == 1, "wrong weak ref count for object after deleting proxy") @@ -304,7 +299,7 @@ "got wrong number of weak reference objects") del ref1, ref2, proxy1, proxy2 - gc.collect() + test_support.gc_collect() self.assert_(weakref.getweakrefcount(o) == 0, "weak reference objects not unlinked from" " referent when discarded.") @@ -318,7 +313,7 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref1 - gc.collect() + test_support.gc_collect() self.assert_(weakref.getweakrefs(o) == [ref2], "list of refs does not match") @@ -326,14 +321,12 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref2 - gc.collect() - gc.collect() - gc.collect() + test_support.gc_collect() self.assert_(weakref.getweakrefs(o) == [ref1], "list of refs does not match") del ref1 - gc.collect() + test_support.gc_collect() self.assert_(weakref.getweakrefs(o) == [], "list of refs not cleared") @@ -535,7 +528,8 @@ del c1, c2, C, D gc.collect() - def XXX_test_callback_in_cycle_resurrection(self): + @test_support.impl_detail + def test_callback_in_cycle_resurrection(self): # We can't guarrantee the behaviour tested with our # current weakref implementations. # If an object and a weakref to it gets collected at the @@ -585,8 +579,9 @@ gc.collect() self.assertEqual(alist, []) - def XXX_test_callbacks_on_callback(self): - # See XXX_test_callback_in_cycle_resurrection above + @test_support.impl_detail + def test_callbacks_on_callback(self): + # See test_callback_in_cycle_resurrection above import gc # Set up weakref callbacks *on* weakref callbacks. @@ -634,9 +629,10 @@ # gc.get/set_threshold does not exist in pypy # The tests calling this function probaly don't test anything # usefull anymore + + if not test_support.check_impl_detail: + return - #thresholds = gc.get_threshold() - #gc.set_threshold(1, 1, 1) gc.collect() class A: pass @@ -657,7 +653,7 @@ weakref.ref(referenced, callback) finally: - pass #gc.set_threshold(*thresholds) + gc.set_threshold(*thresholds) def test_ref_created_during_del(self): # Bug #1377858 @@ -766,27 +762,21 @@ self.assert_(items1 == items2, "cloning of weak-valued dictionary did not work!") del items1, items2 - gc.collect() + test_support.gc_collect() self.assert_(len(dict) == self.COUNT) del objects[0] - gc.collect() - gc.collect() - gc.collect() + test_support.gc_collect() self.assert_(len(dict) == (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o - gc.collect() - gc.collect() - gc.collect() + test_support.gc_collect() self.assert_(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() - gc.collect() - gc.collect() + test_support.gc_collect() self.assertRaises(KeyError, dict.__getitem__, 2) def test_weak_keys(self): @@ -806,18 +796,14 @@ self.assert_(set(items1) == set(items2), "cloning of weak-keyed dictionary did not work!") del items1, items2 - gc.collect() - gc.collect() - gc.collect() + test_support.gc_collect() self.assert_(len(dict) == self.COUNT) del objects[0] - gc.collect() - gc.collect() - gc.collect() + test_support.gc_collect() self.assert_(len(dict) == (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o - gc.collect() + test_support.gc_collect() self.assert_(len(dict) == 0, "deleting the keys did not clear the dictionary") o = Object(42) @@ -935,13 +921,13 @@ self.assert_(len(weakdict) == 2) k, v = weakdict.popitem() self.assert_(len(weakdict) == 1) - if k is key1: + if k == key1: self.assert_(v is value1) else: self.assert_(v is value2) k, v = weakdict.popitem() self.assert_(len(weakdict) == 0) - if k is key1: + if k == key1: self.assert_(v is value1) else: self.assert_(v is value2) @@ -1068,7 +1054,7 @@ for o in objs: d[o] = o.value del o # now the only strong references to keys are in objs - gc.collect() + test_support.gc_collect() # Find the order in which iterkeys sees the keys. objs = d.keys() # Reverse it, so that the iteration implementation of __delitem__ @@ -1087,7 +1073,7 @@ for o in objs: count += 1 del d[o] - gc.collect() + test_support.gc_collect() self.assertEqual(len(d), 0) self.assertEqual(count, 2) Modified: pypy/branch/2.5-merge/pypy/module/_weakref/interp__weakref.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/_weakref/interp__weakref.py (original) +++ pypy/branch/2.5-merge/pypy/module/_weakref/interp__weakref.py Fri Oct 10 16:34:52 2008 @@ -143,7 +143,12 @@ return w_obj -def descr__new__weakref(space, w_subtype, w_obj, w_callable=None): +def descr__new__weakref(space, w_subtype, w_obj, __args__): + args_w, kw_w = __args__.unpack() + if args_w: + w_callable = args_w[0] + else: + w_callable = space.w_None lifeline = w_obj.getweakref() if lifeline is None: lifeline = WeakrefLifeline(space) @@ -183,7 +188,8 @@ __doc__ = """A weak reference to an object 'obj'. A 'callback' can given, which is called with the weak reference as an argument when 'obj' is about to be finalized.""", - __new__ = interp2app(descr__new__weakref), + __new__ = interp2app(descr__new__weakref, + unwrap_spec=[ObjSpace, W_Root, W_Root, Arguments]), __eq__ = interp2app(descr__eq__, unwrap_spec=[ObjSpace, W_Weakref, W_Root]), __ne__ = interp2app(descr__ne__, From antocuni at codespeak.net Fri Oct 10 16:53:15 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 10 Oct 2008 16:53:15 +0200 (CEST) Subject: [pypy-svn] r58914 - in pypy/branch/2.5-merge/pypy: interpreter objspace objspace/std objspace/std/test Message-ID: <20081010145315.A65C216A0AB@codespeak.net> Author: antocuni Date: Fri Oct 10 16:53:15 2008 New Revision: 58914 Modified: pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py pypy/branch/2.5-merge/pypy/objspace/descroperation.py pypy/branch/2.5-merge/pypy/objspace/reflective.py pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py pypy/branch/2.5-merge/pypy/objspace/std/listobject.py pypy/branch/2.5-merge/pypy/objspace/std/objspace.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py pypy/branch/2.5-merge/pypy/objspace/thunk.py Log: (arigo, antocuni) make {get,set,del}slice real multimethods, and implement list.__{get,set,del}slice__ Modified: pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py Fri Oct 10 16:53:15 2008 @@ -588,17 +588,6 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - # support for the deprecated __getslice__, __setslice__, __delslice__ - def getslice(self, w_obj, w_start, w_stop): - w_slice = self.newslice(w_start, w_stop, self.w_None) - return self.getitem(w_obj, w_slice) - def setslice(self, w_obj, w_start, w_stop, w_sequence): - w_slice = self.newslice(w_start, w_stop, self.w_None) - self.setitem(w_obj, w_slice, w_sequence) - def delslice(self, w_obj, w_start, w_stop): - w_slice = self.newslice(w_start, w_stop, self.w_None) - self.delitem(w_obj, w_slice) - def interpclass_w(space, w_obj): """ If w_obj is a wrapped internal interpreter class instance unwrap to it, @@ -1011,6 +1000,9 @@ ('getitem', 'getitem', 2, ['__getitem__']), ('setitem', 'setitem', 3, ['__setitem__']), ('delitem', 'delitem', 2, ['__delitem__']), + ('getslice', 'getslice', 3, ['__getslice__']), + ('setslice', 'setslice', 4, ['__setslice__']), + ('delslice', 'delslice', 3, ['__delslice__']), ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__nonzero__']), Modified: pypy/branch/2.5-merge/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/descroperation.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/descroperation.py Fri Oct 10 16:53:15 2008 @@ -228,6 +228,30 @@ space.wrap("cannot delete items from object")) return space.get_and_call_function(w_descr, w_obj, w_key) + def getslice(space, w_obj, w_start, w_stop): + w_descr = space.lookup(w_obj, '__getslice__') + if w_descr is None: + w_slice = space.newslice(w_start, w_stop, space.w_None) + return space.getitem(w_obj, w_slice) + w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) + return space.get_and_call_function(w_descr, w_obj, w_start, w_stop) + + def setslice(space, w_obj, w_start, w_stop, w_sequence): + w_descr = space.lookup(w_obj, '__setslice__') + if w_descr is None: + w_slice = space.newslice(w_start, w_stop, space.w_None) + return space.setitem(w_obj, w_slice, w_sequence) + w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) + return space.get_and_call_function(w_descr, w_obj, w_start, w_stop, w_sequence) + + def delslice(space, w_obj, w_start, w_stop): + w_descr = space.lookup(w_obj, '__delslice__') + if w_descr is None: + w_slice = space.newslice(w_start, w_stop, space.w_None) + return space.delitem(w_obj, w_slice) + w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) + return space.get_and_call_function(w_descr, w_obj, w_start, w_stop) + def pow(space, w_obj1, w_obj2, w_obj3): w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) @@ -453,6 +477,35 @@ return (space.lookup(w_obj, '__int__') is not None or space.lookup(w_obj, '__float__') is not None) + + +# what is the maximum value slices can get on CPython? +# we need to stick to that value, because fake.py etc. +class Temp: + def __getslice__(self, i, j): + return j +slice_max = Temp()[:] +del Temp + +def old_slice_range(space, w_obj, w_start, w_stop): + """Only for backward compatibility for __getslice__()&co methods.""" + if space.is_w(w_start, space.w_None): + w_start = space.wrap(0) + else: + w_start = space.wrap(space.getindex_w(w_start, None)) + if space.is_true(space.lt(w_start, space.wrap(0))): + w_start = space.add(w_start, space.len(w_obj)) + # NB. the language ref is inconsistent with the new-style class + # behavior when w_obj doesn't implement __len__(), so we just + # ignore this case. + if space.is_w(w_stop, space.w_None): + w_stop = space.wrap(slice_max) + else: + w_stop = space.wrap(space.getindex_w(w_stop, None)) + if space.is_true(space.lt(w_stop, space.wrap(0))): + w_stop = space.add(w_stop, space.len(w_obj)) + return w_start, w_stop + # regular methods def helpers def _make_binop_impl(symbol, specialnames): @@ -649,5 +702,3 @@ 'ord', 'unichr', 'unicode']: raise Exception, "missing def for operation %s" % _name - - Modified: pypy/branch/2.5-merge/pypy/objspace/reflective.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/reflective.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/reflective.py Fri Oct 10 16:53:15 2008 @@ -89,6 +89,14 @@ return parentfn(w_arg1, w_arg2, w_arg3) finally: reset_reflective_space(space, w_old_reflectivespace) + elif args == 4: + def func(self, space, w_arg1, w_arg2, w_arg3, w_arg4): + w_old_reflectivespace = get_reflective_space(space) + set_reflectivespace(space, self.w_reflectivespace) + try: + return parentfn(w_arg1, w_arg2, w_arg3, w_arg4) + finally: + reset_reflective_space(space, w_old_reflectivespace) else: raise NotImplementedError unwrap_spec = ["self", ObjSpace] + [W_Root] * args Modified: pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py Fri Oct 10 16:53:15 2008 @@ -22,6 +22,7 @@ 'len', 'nonzero', 'repr', 'str', 'hash', 'neg', 'invert', 'index', 'iter', 'next', 'buffer', 'getitem', 'setitem', 'int', + 'getslice', 'setslice', # in-place 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', 'inplace_mod', 'inplace_pow', @@ -32,7 +33,8 @@ KNOWN_MISSING = ['getattr', # mostly non-builtins or optimized by CALL_METHOD 'setattr', 'delattr', 'userdel', # mostly for non-builtins 'get', 'set', 'delete', # uncommon (except on functions) - 'delitem', 'abs', 'hex', 'oct', # rare stuff? + 'delitem', 'delslice', # rare stuff? + 'abs', 'hex', 'oct', # rare stuff? 'pos', 'divmod', 'cmp', # rare stuff? 'float', 'long', 'coerce', # rare stuff? ] Modified: pypy/branch/2.5-merge/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/listobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/listobject.py Fri Oct 10 16:53:15 2008 @@ -80,6 +80,30 @@ start += step return w_res +def normalize_slice(space, w_list, w_start, w_stop): + start = space.int_w(w_start) + stop = space.int_w(w_stop) + length = len(w_list.wrappeditems) + if start < 0: + start = 0 + if stop > length: + stop = length + if stop < start: + stop = start + return start, stop + +def getslice__List_ANY_ANY(space, w_list, w_start, w_stop): + start, stop = normalize_slice(space, w_list, w_start, w_stop) + return W_ListObject(w_list.wrappeditems[start:stop]) + +def setslice__List_ANY_ANY_ANY(space, w_list, w_start, w_stop, w_sequence): + start, stop = normalize_slice(space, w_list, w_start, w_stop) + _setitem_slice_helper(space, w_list, start, 1, stop-start, w_sequence) + +def delslice__List_ANY_ANY(space, w_list, w_start, w_stop): + start, stop = normalize_slice(space, w_list, w_start, w_stop) + _delitem_slice_helper(space, w_list, start, 1, stop-start) + def contains__List_ANY(space, w_list, w_obj): # needs to be safe against eq_w() mutating the w_list behind our back i = 0 @@ -190,38 +214,35 @@ space.wrap("list deletion index out of range")) return space.w_None + def delitem__List_Slice(space, w_list, w_slice): start, stop, step, slicelength = w_slice.indices4(space, len(w_list.wrappeditems)) + _delitem_slice_helper(space, w_list, start, step, slicelength) +def _delitem_slice_helper(space, w_list, start, step, slicelength): if slicelength==0: return if step < 0: start = start + step * (slicelength-1) step = -step - # stop is invalid if step == 1: - _del_slice(w_list, start, start+slicelength) + assert start >= 0 + assert slicelength >= 0 + del w_list.wrappeditems[start:start+slicelength] else: items = w_list.wrappeditems n = len(items) - - recycle = [None] * slicelength i = start - # keep a reference to the objects to be removed, - # preventing side effects during destruction - recycle[0] = items[i] - for discard in range(1, slicelength): j = i+1 i += step while j < i: items[j-discard] = items[j] j += 1 - recycle[discard] = items[i] j = i+1 while j < n: @@ -229,13 +250,7 @@ j += 1 start = n - slicelength assert start >= 0 # annotator hint - # XXX allow negative indices in rlist del items[start:] - # now we can destruct recycle safely, regardless of - # side-effects to the list - del recycle[:] - - return space.w_None def setitem__List_ANY_ANY(space, w_list, w_index, w_any): idx = get_list_index(space, w_index) @@ -246,23 +261,25 @@ space.wrap("list index out of range")) return space.w_None -def setitem__List_Slice_List(space, w_list, w_slice, w_list2): - l = w_list2.wrappeditems - return _setitem_slice_helper(space, w_list, w_slice, l, len(l)) - def setitem__List_Slice_ANY(space, w_list, w_slice, w_iterable): - l = space.unpackiterable(w_iterable) - return _setitem_slice_helper(space, w_list, w_slice, l, len(l)) - -def _setitem_slice_helper(space, w_list, w_slice, sequence2, len2): oldsize = len(w_list.wrappeditems) start, stop, step, slicelength = w_slice.indices4(space, oldsize) + _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable) + +def _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable): + if isinstance(w_iterable, W_ListObject): + sequence2 = w_iterable.wrappeditems + else: + sequence2 = space.unpackiterable(w_iterable) + assert slicelength >= 0 items = w_list.wrappeditems - + oldsize = len(items) + len2 = len(sequence2) if step == 1: # Support list resizing for non-extended slices - delta = len2 - slicelength - if delta >= 0: + delta = slicelength - len2 + if delta < 0: + delta = -delta newsize = oldsize + delta # XXX support this in rlist! items += [None] * delta @@ -271,9 +288,10 @@ while i >= lim: items[i] = items[i-delta] i -= 1 + elif start >= 0: + del items[start:start+delta] else: - # shrinking requires the careful memory management of _del_slice() - _del_slice(w_list, start, start-delta) + assert delta==0 elif len2 != slicelength: # No resize for extended slices raise OperationError(space.w_ValueError, space.wrap("attempt to " "assign sequence of size %d to extended slice of size %d" % @@ -290,14 +308,13 @@ items[start] = sequence2[i] start -= step i -= 1 - return space.w_None + return else: # Make a shallow copy to more easily handle the reversal case sequence2 = list(sequence2) for i in range(len2): items[start] = sequence2[i] start += step - return space.w_None app = gateway.applevel(""" def listrepr(currently_in_repr, l): @@ -350,26 +367,6 @@ w_list.wrappeditems += space.unpackiterable(w_any) return space.w_None -def _del_slice(w_list, ilow, ihigh): - """ similar to the deletion part of list_ass_slice in CPython """ - items = w_list.wrappeditems - n = len(items) - if ilow < 0: - ilow = 0 - elif ilow > n: - ilow = n - if ihigh < ilow: - ihigh = ilow - elif ihigh > n: - ihigh = n - # keep a reference to the objects to be removed, - # preventing side effects during destruction - recycle = items[ilow:ihigh] - del items[ilow:ihigh] - # now we can destruct recycle safely, regardless of - # side-effects to the list - del recycle[:] - # note that the default value will come back wrapped!!! def list_pop__List_ANY(space, w_list, w_idx=-1): items = w_list.wrappeditems Modified: pypy/branch/2.5-merge/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/objspace.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/objspace.py Fri Oct 10 16:53:15 2008 @@ -764,33 +764,6 @@ else: return ObjSpace.call_method(self, w_obj, methname, *arg_w) - # support for the deprecated __getslice__, __setslice__, __delslice__ - - def getslice(self, w_obj, w_start, w_stop): - w_descr = self.lookup(w_obj, '__getslice__') - if w_descr is not None: - w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) - return self.get_and_call_function(w_descr, w_obj, w_start, w_stop) - else: - return ObjSpace.getslice(self, w_obj, w_start, w_stop) - - def setslice(self, w_obj, w_start, w_stop, w_sequence): - w_descr = self.lookup(w_obj, '__setslice__') - if w_descr is not None: - w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) - self.get_and_call_function(w_descr, w_obj, w_start, w_stop, - w_sequence) - else: - ObjSpace.setslice(self, w_obj, w_start, w_stop, w_sequence) - - def delslice(self, w_obj, w_start, w_stop): - w_descr = self.lookup(w_obj, '__delslice__') - if w_descr is not None: - w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) - self.get_and_call_function(w_descr, w_obj, w_start, w_stop) - else: - ObjSpace.delslice(self, w_obj, w_start, w_stop) - def raise_key_error(self, w_key): e = self.call_function(self.w_KeyError, w_key) raise OperationError(self.w_KeyError, e) @@ -820,32 +793,3 @@ del mm pow.extras['defaults'] = (None,) - - -# what is the maximum value slices can get on CPython? -# we need to stick to that value, because fake.py etc. -class Temp: - def __getslice__(self, i, j): - return j -slice_max = Temp()[:] -del Temp - - -def old_slice_range(space, w_obj, w_start, w_stop): - """Only for backward compatibility for __getslice__()&co methods.""" - if space.is_w(w_start, space.w_None): - w_start = space.wrap(0) - else: - w_start = space.wrap(space.getindex_w(w_start, None)) - if space.is_true(space.lt(w_start, space.wrap(0))): - w_start = space.add(w_start, space.len(w_obj)) - # NB. the language ref is inconsistent with the new-style class - # behavior when w_obj doesn't implement __len__(), so we just - # ignore this case. - if space.is_w(w_stop, space.w_None): - w_stop = space.wrap(slice_max) - else: - w_stop = space.wrap(space.getindex_w(w_stop, None)) - if space.is_true(space.lt(w_stop, space.wrap(0))): - w_stop = space.add(w_stop, space.len(w_obj)) - return w_start, w_stop Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py Fri Oct 10 16:53:15 2008 @@ -39,6 +39,15 @@ # These few here ^ would have failed before, but for good coverage, # all the list methods etc. should be tested also... + def test___getslice__(self): + skip("don't care for now") + + def test___setslice__(self): + skip("don't care for now") + + def test___delslice__(self): + skip("don't care for now") + class AppTest_ListMultiObject(BaseAppTest_ListMultiObject): def setup_class(cls): BaseAppTest_ListMultiObject.setup_class(cls) Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py Fri Oct 10 16:53:15 2008 @@ -754,3 +754,18 @@ A() while lst: keepalive.append(lst[:]) + + def test___getslice__(self): + l = [1,2,3,4] + res = l.__getslice__(0, 2) + assert res == [1, 2] + + def test___setslice__(self): + l = [1,2,3,4] + l.__setslice__(0, 2, [5, 6]) + assert l == [5, 6, 3, 4] + + def test___delslice__(self): + l = [1,2,3,4] + l.__delslice__(0, 2) + assert l == [3, 4] Modified: pypy/branch/2.5-merge/pypy/objspace/thunk.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/thunk.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/thunk.py Fri Oct 10 16:53:15 2008 @@ -193,6 +193,13 @@ w2 = force(space, w2) w3 = force(space, w3) return parentfn(w1, w2, w3, *extra) + elif nb_args == 4: + def proxy(w1, w2, w3, w4, *extra): + w1 = force(space, w1) + w2 = force(space, w2) + w3 = force(space, w3) + w4 = force(space, w4) + return parentfn(w1, w2, w3, w4, *extra) else: raise NotImplementedError("operation %r has arity %d" % (opname, nb_args)) From iko at codespeak.net Fri Oct 10 17:09:49 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 10 Oct 2008 17:09:49 +0200 (CEST) Subject: [pypy-svn] r58915 - in pypy/branch/2.5-merge/pypy/interpreter: pyparser test Message-ID: <20081010150949.4E68C169F9F@codespeak.net> Author: iko Date: Fri Oct 10 17:09:48 2008 New Revision: 58915 Modified: pypy/branch/2.5-merge/pypy/interpreter/pyparser/astbuilder.py pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py Log: (iko, cfbolz) Make parser not blow up on bare yield statement Modified: pypy/branch/2.5-merge/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/pyparser/astbuilder.py Fri Oct 10 17:09:48 2008 @@ -877,18 +877,18 @@ index += 1 builder.push(ast.From(from_name, names, level, atoms[0].lineno)) +def _make_yield_tree(builder, nb): + atoms = get_atoms(builder, nb) + if len(atoms) == 1: + return ast.Yield(ast.Const(builder.wrap_none()), atoms[0].lineno) + else: + return ast.Yield(atoms[1], atoms[0].lineno) def build_yield_stmt(builder, nb): - atoms = get_atoms(builder, nb) - lineno = atoms[0].lineno - builder.push(ast.Discard(ast.Yield(atoms[1], lineno), lineno)) + builder.push(ast.Discard(_make_yield_tree(builder, nb))) def build_yield_expr(builder, nb): - atoms = get_atoms(builder, nb) - if len(atoms) == 1: - builder.push(ast.Yield(ast.Const(builder.wrap_none()), atoms[0].lineno)) - else: - builder.push(ast.Yield(atoms[1], atoms[0].lineno)) + builder.push(_make_yield_tree(builder, nb)) def build_continue_stmt(builder, nb): atoms = get_atoms(builder, nb) Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py Fri Oct 10 17:09:48 2008 @@ -276,6 +276,11 @@ exec "1 if True else 2" warnings.simplefilter('default', SyntaxWarning) +class AppTestYield(Py25AppTest): + def test_bare_yield(self): + s = "def f():\n yield" + + exec s class AppTestWith(Py25AppTest): def test_with_simple(self): From arigo at codespeak.net Fri Oct 10 18:00:56 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 18:00:56 +0200 (CEST) Subject: [pypy-svn] r58916 - in pypy/branch/2.5-merge/pypy/interpreter: . test Message-ID: <20081010160056.9C5DD16A0B5@codespeak.net> Author: arigo Date: Fri Oct 10 18:00:52 2008 New Revision: 58916 Modified: pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py pypy/branch/2.5-merge/pypy/interpreter/executioncontext.py pypy/branch/2.5-merge/pypy/interpreter/function.py pypy/branch/2.5-merge/pypy/interpreter/pyframe.py pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py pypy/branch/2.5-merge/pypy/interpreter/test/test_executioncontext.py Log: (antocuni, arigo) Merge the builtin-profiling branch, which adds support for sending the c_call, c_return and c_exception events to the app-level profilers set by sys.setprofile(). Modified: pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py Fri Oct 10 18:00:52 2008 @@ -702,9 +702,19 @@ return self.call_args(w_func, args) def call_valuestack(self, w_func, nargs, frame): + from pypy.interpreter.function import Function, Method, is_builtin_code + if frame.is_being_profiled and is_builtin_code(w_func): + # XXX: this code is copied&pasted :-( from the slow path below + # call_valuestack(). + args = frame.make_arguments(nargs) + try: + return self.call_args_and_c_profile(frame, w_func, args) + finally: + if isinstance(args, ArgumentsFromValuestack): + args.frame = None + if not self.config.objspace.disable_call_speedhacks: # XXX start of hack for performance - from pypy.interpreter.function import Function, Method hint(w_func.__class__, promote=True) if isinstance(w_func, Method): w_inst = w_func.w_instance @@ -729,6 +739,17 @@ if isinstance(args, ArgumentsFromValuestack): args.frame = None + def call_args_and_c_profile(self, frame, w_func, args): + ec = self.getexecutioncontext() + ec.c_call_trace(frame, w_func) + try: + w_res = self.call_args(w_func, args) + except OperationError, e: + ec.c_exception_trace(frame, e.w_value) + raise + ec.c_return_trace(frame, w_res) + return w_res + 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) Modified: pypy/branch/2.5-merge/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/executioncontext.py Fri Oct 10 18:00:52 2008 @@ -71,8 +71,7 @@ def leave(self, ec): self.framestack = ec.framestack self.w_tracefunc = ec.w_tracefunc - self.profilefunc = ec.profilefunc - self.w_profilefuncarg = ec.w_profilefuncarg + self.setllprofile(ec.profilefunc, ec.w_profilefuncarg) self.is_tracing = ec.is_tracing # the following interface is for pickling and unpickling @@ -104,10 +103,43 @@ space.setitem(w_globals, w_key, w_value) return w_globals + def c_call_trace(self, frame, w_func): + "Profile the call of a builtin function" + if self.profilefunc is None: + frame.is_being_profiled = False + else: + self._trace(frame, 'c_call', w_func) + + def c_return_trace(self, frame, w_retval): + "Profile the return from a builtin function" + if self.profilefunc is None: + frame.is_being_profiled = False + else: + self._trace(frame, 'c_return', w_retval) + + def c_exception_trace(self, frame, w_exc): + "Profile function called upon OperationError." + if self.profilefunc is None: + frame.is_being_profiled = False + else: + self._trace(frame, 'c_exception', w_exc) + + def _llprofile(self, event, w_arg): + fr = self.framestack.items + space = self.space + w_callback = self.profilefunc + if w_callback is not None: + frame = None + if fr: + frame = fr[0] + self.profilefunc(space, self.w_profilefuncarg, frame, event, w_arg) + def call_trace(self, frame): "Trace the call of a function" if self.w_tracefunc is not None or self.profilefunc is not None: self._trace(frame, 'call', self.space.w_None) + if self.profilefunc: + frame.is_being_profiled = True def return_trace(self, frame, w_retval): "Trace the return from a function" @@ -157,13 +189,15 @@ self.profilefunc = None self.w_profilefuncarg = None else: - self.w_profilefuncarg = w_func - self.profilefunc = app_profile_call + self.setllprofile(app_profile_call, w_func) def setllprofile(self, func, w_arg): self.profilefunc = func - if func is not None and w_arg is None: - raise ValueError("Cannot call setllprofile with real None") + if func is not None: + if w_arg is None: + raise ValueError("Cannot call setllprofile with real None") + for frame in self.framestack.items: + frame.is_being_profiled = True self.w_profilefuncarg = w_arg def call_tracing(self, w_func, w_args): @@ -176,7 +210,7 @@ self.is_tracing = is_tracing def _trace(self, frame, event, w_arg, operr=None): - if self.is_tracing or frame.hide(): + if self.is_tracing or frame.hide() or frame is None: return space = self.space @@ -212,7 +246,8 @@ # Profile cases if self.profilefunc is not None: - if event not in ['leaveframe', 'call']: + if event not in ['leaveframe', 'call', 'c_call', + 'c_return', 'c_exception']: return last_exception = None Modified: pypy/branch/2.5-merge/pypy/interpreter/function.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/function.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/function.py Fri Oct 10 18:00:52 2008 @@ -33,7 +33,8 @@ def __repr__(self): # return "function %s.%s" % (self.space, self.name) # maybe we want this shorter: - return "" % getattr(self, 'name', '?') + name = getattr(self, 'name', '?') + return "<%s %s>" % (self.__class__.__name__, name) def call_args(self, args): # delegate activation to code @@ -519,3 +520,13 @@ def descr_function_repr(self): return self.space.wrap('' % (self.name,)) + +def is_builtin_code(w_func): + from pypy.interpreter.gateway import BuiltinCode + if isinstance(w_func, Method): + w_func = w_func.w_function + if isinstance(w_func, Function): + code = w_func.getcode() + else: + code = None + return isinstance(code, BuiltinCode) Modified: pypy/branch/2.5-merge/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/pyframe.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/pyframe.py Fri Oct 10 18:00:52 2008 @@ -43,6 +43,7 @@ instr_lb = 0 instr_ub = -1 instr_prev = -1 + is_being_profiled = False def __init__(self, space, code, w_globals, closure): self = hint(self, access_directly=True) Modified: pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py Fri Oct 10 18:00:52 2008 @@ -848,6 +848,7 @@ def call_function(f, oparg, w_star=None, w_starstar=None): from pypy.rlib import rstack # for resume points + from pypy.interpreter.function import is_builtin_code n_arguments = oparg & 0xff n_keywords = (oparg>>8) & 0xff @@ -857,7 +858,10 @@ arguments = f.popvalues(n_arguments) args = Arguments(f.space, arguments, keywords, w_star, w_starstar) w_function = f.popvalue() - w_result = f.space.call_args(w_function, args) + if f.is_being_profiled and is_builtin_code(w_function): + w_result = f.space.call_args_and_c_profile(f, w_function, args) + else: + w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) f.pushvalue(w_result) Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_executioncontext.py Fri Oct 10 18:00:52 2008 @@ -62,7 +62,6 @@ assert space.sys.checkinterval / 10 < i < space.sys.checkinterval * 3 def test_llprofile(self): - py.test.skip("not working yet") l = [] def profile_func(space, w_arg, frame, event, w_aarg): @@ -72,9 +71,125 @@ space = self.space space.getexecutioncontext().setllprofile(profile_func, space.w_None) space.appexec([], """(): - l = [] - l.append(3) + pass """) space.getexecutioncontext().setllprofile(None, None) - assert l == ['call', 'return', 'call', 'c_call', 'c_return', 'return'] + assert l == ['call', 'return', 'call', 'return'] + + def test_llprofile_c_call(self): + l = [] + + def profile_func(space, w_arg, frame, event, w_aarg): + assert w_arg is space.w_None + l.append(event) + + space = self.space + space.getexecutioncontext().setllprofile(profile_func, space.w_None) + + def check_snippet(snippet): + space.appexec([], """(): + %s + return + """ % snippet) + space.getexecutioncontext().setllprofile(None, None) + assert l == ['call', 'return', 'call', 'c_call', 'c_return', 'return'] + + check_snippet('l = []; l.append(42)') + check_snippet('max(1, 2)') + check_snippet('args = (1, 2); max(*args)') + check_snippet('max(1, 2, **{})') + check_snippet('args = (1, 2); max(*args, **{})') + check_snippet('abs(val=0)') + + def test_llprofile_c_exception(self): + l = [] + + def profile_func(space, w_arg, frame, event, w_aarg): + assert w_arg is space.w_None + l.append(event) + + space = self.space + space.getexecutioncontext().setllprofile(profile_func, space.w_None) + + def check_snippet(snippet): + space.appexec([], """(): + try: + %s + except: + pass + return + """ % snippet) + space.getexecutioncontext().setllprofile(None, None) + assert l == ['call', 'return', 'call', 'c_call', 'c_exception', 'return'] + + check_snippet('d = {}; d.__getitem__(42)') + def test_c_call_setprofile_outer_frame(self): + space = self.space + w_events = space.appexec([], """(): + import sys + l = [] + def profile(frame, event, arg): + l.append(event) + + def foo(): + sys.setprofile(profile) + + def bar(): + foo() + max(1, 2) + + bar() + sys.setprofile(None) + return l + """) + events = space.unwrap(w_events) + assert events == ['return', 'c_call', 'c_return', 'return', 'c_call'] + + def test_c_call_setprofile_strange_method(self): + space = self.space + w_events = space.appexec([], """(): + import sys + class A(object): + def __init__(self, value): + self.value = value + def meth(self): + pass + MethodType = type(A.meth) + strangemeth = MethodType(A, 42, int) + l = [] + def profile(frame, event, arg): + l.append(event) + + def foo(): + sys.setprofile(profile) + + def bar(): + foo() + strangemeth() + + bar() + sys.setprofile(None) + return l + """) + events = space.unwrap(w_events) + assert events == ['return', 'call', 'return', 'return', 'c_call'] + + def test_c_call_profiles_immediately(self): + space = self.space + w_events = space.appexec([], """(): + import sys + l = [] + def profile(frame, event, arg): + l.append(event) + + def bar(): + sys.setprofile(profile) + max(3, 4) + + bar() + sys.setprofile(None) + return l + """) + events = space.unwrap(w_events) + assert events == ['c_call', 'c_return', 'return', 'c_call'] From arigo at codespeak.net Fri Oct 10 18:01:02 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 18:01:02 +0200 (CEST) Subject: [pypy-svn] r58917 - pypy/branch/builtin-profiling Message-ID: <20081010160102.916FB16A0CD@codespeak.net> Author: arigo Date: Fri Oct 10 18:01:01 2008 New Revision: 58917 Removed: pypy/branch/builtin-profiling/ Log: (antocuni, arigo) Remove merged branch. From fijal at codespeak.net Fri Oct 10 18:15:05 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 18:15:05 +0200 (CEST) Subject: [pypy-svn] r58918 - pypy/build/bot2/pypybuildbot Message-ID: <20081010161505.13B6716A043@codespeak.net> Author: fijal Date: Fri Oct 10 18:15:03 2008 New Revision: 58918 Modified: pypy/build/bot2/pypybuildbot/master.py Log: (fijal, pedronis) Move bigdog-vm1 to it's own builder Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Oct 10 18:15:03 2008 @@ -32,6 +32,7 @@ LINUX32 = "own-linux-x86-32" CPYLINUX32 = "pypy-c-lib-python-linux-x86-32" CPYWIN32 = "pypy-c-lib-python-win-32" +CPYLINUX32_VM = 'pypy-c-lib-python-linux-x86-32vm' BuildmasterConfig = { 'slavePortnum': slavePortnum, @@ -53,10 +54,15 @@ "factory": pypyOwnTestFactory }, {"name": CPYLINUX32, - "slavenames": ["wyvern", "cobra", "bigdogvm1"], + "slavenames": ["wyvern", "cobra"], "builddir": CPYLINUX32, "factory": pypyTranslatedLibPythonTestFactory }, + {"name" : CPYLINUX32_VM, + "slavenames": ['bigdogvm1'], + "builddir": CPYLINUX32_VM, + "factory": pypyTranslatedLibPythonTestFactory + }, {"name": CPYWIN32, "slavenames": ["winxp32-py2.5"], "builddir": CPYWIN32, From arigo at codespeak.net Fri Oct 10 18:15:44 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 18:15:44 +0200 (CEST) Subject: [pypy-svn] r58919 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081010161544.1AAF316A094@codespeak.net> Author: arigo Date: Fri Oct 10 18:15:43 2008 New Revision: 58919 Modified: pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py Log: We cannot support {get,set,del}slice in builtinshortcut right now (see comment there). Modified: pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py Fri Oct 10 18:15:43 2008 @@ -22,7 +22,6 @@ 'len', 'nonzero', 'repr', 'str', 'hash', 'neg', 'invert', 'index', 'iter', 'next', 'buffer', 'getitem', 'setitem', 'int', - 'getslice', 'setslice', # in-place 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', 'inplace_mod', 'inplace_pow', @@ -33,11 +32,16 @@ KNOWN_MISSING = ['getattr', # mostly non-builtins or optimized by CALL_METHOD 'setattr', 'delattr', 'userdel', # mostly for non-builtins 'get', 'set', 'delete', # uncommon (except on functions) - 'delitem', 'delslice', # rare stuff? + 'getslice', 'setslice', 'delslice', # see below + 'delitem', # rare stuff? 'abs', 'hex', 'oct', # rare stuff? 'pos', 'divmod', 'cmp', # rare stuff? 'float', 'long', 'coerce', # rare stuff? ] +# We cannot support {get,set,del}slice right now because +# DescrOperation.{get,set,del}slice do a bit more work than just call +# the special methods: they call old_slice_range(). See e.g. +# test_builtinshortcut.AppTestString. for _name, _, _, _specialmethods in ObjSpace.MethodTable: if _specialmethods: Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py Fri Oct 10 18:15:43 2008 @@ -1,5 +1,6 @@ from pypy.objspace.std.test import test_userobject from pypy.objspace.std.test import test_set +from pypy.objspace.std.test import test_stringobject WITH_BUILTINSHORTCUT = {'objspace.std.builtinshortcut': True} @@ -38,3 +39,8 @@ def setup_class(cls): from pypy import conftest cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) + +class AppTestString(test_stringobject.AppTestStringObject): + def setup_class(cls): + from pypy import conftest + cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) From fijal at codespeak.net Fri Oct 10 18:19:09 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 18:19:09 +0200 (CEST) Subject: [pypy-svn] r58920 - pypy/build/bot2/codespeak-html Message-ID: <20081010161909.E52FC16A0C2@codespeak.net> Author: fijal Date: Fri Oct 10 18:19:06 2008 New Revision: 58920 Modified: pypy/build/bot2/codespeak-html/index.html Log: (fijal, pedronis) add link to the list of builders Modified: pypy/build/bot2/codespeak-html/index.html ============================================================================== --- pypy/build/bot2/codespeak-html/index.html (original) +++ pypy/build/bot2/codespeak-html/index.html Fri Oct 10 18:19:06 2008 @@ -23,6 +23,7 @@
  • Recent Builds are summarized here, one per line.
  • +
  • Builders information
  • Buildslave information
  • ChangeSource information.
  • From arigo at codespeak.net Fri Oct 10 18:26:05 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 18:26:05 +0200 (CEST) Subject: [pypy-svn] r58921 - in pypy/branch/2.5-merge/pypy: interpreter objspace objspace/std objspace/std/test Message-ID: <20081010162605.45F8516A107@codespeak.net> Author: arigo Date: Fri Oct 10 18:26:04 2008 New Revision: 58921 Modified: pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py pypy/branch/2.5-merge/pypy/objspace/descroperation.py pypy/branch/2.5-merge/pypy/objspace/reflective.py pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py pypy/branch/2.5-merge/pypy/objspace/std/listobject.py pypy/branch/2.5-merge/pypy/objspace/std/objspace.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py pypy/branch/2.5-merge/pypy/objspace/thunk.py Log: Revert r58914 and r58919, moving it to a branch. Modified: pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/baseobjspace.py Fri Oct 10 18:26:04 2008 @@ -588,6 +588,17 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s + # support for the deprecated __getslice__, __setslice__, __delslice__ + def getslice(self, w_obj, w_start, w_stop): + w_slice = self.newslice(w_start, w_stop, self.w_None) + return self.getitem(w_obj, w_slice) + def setslice(self, w_obj, w_start, w_stop, w_sequence): + w_slice = self.newslice(w_start, w_stop, self.w_None) + self.setitem(w_obj, w_slice, w_sequence) + def delslice(self, w_obj, w_start, w_stop): + w_slice = self.newslice(w_start, w_stop, self.w_None) + self.delitem(w_obj, w_slice) + def interpclass_w(space, w_obj): """ If w_obj is a wrapped internal interpreter class instance unwrap to it, @@ -1021,9 +1032,6 @@ ('getitem', 'getitem', 2, ['__getitem__']), ('setitem', 'setitem', 3, ['__setitem__']), ('delitem', 'delitem', 2, ['__delitem__']), - ('getslice', 'getslice', 3, ['__getslice__']), - ('setslice', 'setslice', 4, ['__setslice__']), - ('delslice', 'delslice', 3, ['__delslice__']), ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__nonzero__']), Modified: pypy/branch/2.5-merge/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/descroperation.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/descroperation.py Fri Oct 10 18:26:04 2008 @@ -228,30 +228,6 @@ space.wrap("cannot delete items from object")) return space.get_and_call_function(w_descr, w_obj, w_key) - def getslice(space, w_obj, w_start, w_stop): - w_descr = space.lookup(w_obj, '__getslice__') - if w_descr is None: - w_slice = space.newslice(w_start, w_stop, space.w_None) - return space.getitem(w_obj, w_slice) - w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) - return space.get_and_call_function(w_descr, w_obj, w_start, w_stop) - - def setslice(space, w_obj, w_start, w_stop, w_sequence): - w_descr = space.lookup(w_obj, '__setslice__') - if w_descr is None: - w_slice = space.newslice(w_start, w_stop, space.w_None) - return space.setitem(w_obj, w_slice, w_sequence) - w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) - return space.get_and_call_function(w_descr, w_obj, w_start, w_stop, w_sequence) - - def delslice(space, w_obj, w_start, w_stop): - w_descr = space.lookup(w_obj, '__delslice__') - if w_descr is None: - w_slice = space.newslice(w_start, w_stop, space.w_None) - return space.delitem(w_obj, w_slice) - w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) - return space.get_and_call_function(w_descr, w_obj, w_start, w_stop) - def pow(space, w_obj1, w_obj2, w_obj3): w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) @@ -477,35 +453,6 @@ return (space.lookup(w_obj, '__int__') is not None or space.lookup(w_obj, '__float__') is not None) - - -# what is the maximum value slices can get on CPython? -# we need to stick to that value, because fake.py etc. -class Temp: - def __getslice__(self, i, j): - return j -slice_max = Temp()[:] -del Temp - -def old_slice_range(space, w_obj, w_start, w_stop): - """Only for backward compatibility for __getslice__()&co methods.""" - if space.is_w(w_start, space.w_None): - w_start = space.wrap(0) - else: - w_start = space.wrap(space.getindex_w(w_start, None)) - if space.is_true(space.lt(w_start, space.wrap(0))): - w_start = space.add(w_start, space.len(w_obj)) - # NB. the language ref is inconsistent with the new-style class - # behavior when w_obj doesn't implement __len__(), so we just - # ignore this case. - if space.is_w(w_stop, space.w_None): - w_stop = space.wrap(slice_max) - else: - w_stop = space.wrap(space.getindex_w(w_stop, None)) - if space.is_true(space.lt(w_stop, space.wrap(0))): - w_stop = space.add(w_stop, space.len(w_obj)) - return w_start, w_stop - # regular methods def helpers def _make_binop_impl(symbol, specialnames): @@ -702,3 +649,5 @@ 'ord', 'unichr', 'unicode']: raise Exception, "missing def for operation %s" % _name + + Modified: pypy/branch/2.5-merge/pypy/objspace/reflective.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/reflective.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/reflective.py Fri Oct 10 18:26:04 2008 @@ -89,14 +89,6 @@ return parentfn(w_arg1, w_arg2, w_arg3) finally: reset_reflective_space(space, w_old_reflectivespace) - elif args == 4: - def func(self, space, w_arg1, w_arg2, w_arg3, w_arg4): - w_old_reflectivespace = get_reflective_space(space) - set_reflectivespace(space, self.w_reflectivespace) - try: - return parentfn(w_arg1, w_arg2, w_arg3, w_arg4) - finally: - reset_reflective_space(space, w_old_reflectivespace) else: raise NotImplementedError unwrap_spec = ["self", ObjSpace] + [W_Root] * args Modified: pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/builtinshortcut.py Fri Oct 10 18:26:04 2008 @@ -32,16 +32,10 @@ KNOWN_MISSING = ['getattr', # mostly non-builtins or optimized by CALL_METHOD 'setattr', 'delattr', 'userdel', # mostly for non-builtins 'get', 'set', 'delete', # uncommon (except on functions) - 'getslice', 'setslice', 'delslice', # see below - 'delitem', # rare stuff? - 'abs', 'hex', 'oct', # rare stuff? + 'delitem', 'abs', 'hex', 'oct', # rare stuff? 'pos', 'divmod', 'cmp', # rare stuff? 'float', 'long', 'coerce', # rare stuff? ] -# We cannot support {get,set,del}slice right now because -# DescrOperation.{get,set,del}slice do a bit more work than just call -# the special methods: they call old_slice_range(). See e.g. -# test_builtinshortcut.AppTestString. for _name, _, _, _specialmethods in ObjSpace.MethodTable: if _specialmethods: Modified: pypy/branch/2.5-merge/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/listobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/listobject.py Fri Oct 10 18:26:04 2008 @@ -80,30 +80,6 @@ start += step return w_res -def normalize_slice(space, w_list, w_start, w_stop): - start = space.int_w(w_start) - stop = space.int_w(w_stop) - length = len(w_list.wrappeditems) - if start < 0: - start = 0 - if stop > length: - stop = length - if stop < start: - stop = start - return start, stop - -def getslice__List_ANY_ANY(space, w_list, w_start, w_stop): - start, stop = normalize_slice(space, w_list, w_start, w_stop) - return W_ListObject(w_list.wrappeditems[start:stop]) - -def setslice__List_ANY_ANY_ANY(space, w_list, w_start, w_stop, w_sequence): - start, stop = normalize_slice(space, w_list, w_start, w_stop) - _setitem_slice_helper(space, w_list, start, 1, stop-start, w_sequence) - -def delslice__List_ANY_ANY(space, w_list, w_start, w_stop): - start, stop = normalize_slice(space, w_list, w_start, w_stop) - _delitem_slice_helper(space, w_list, start, 1, stop-start) - def contains__List_ANY(space, w_list, w_obj): # needs to be safe against eq_w() mutating the w_list behind our back i = 0 @@ -214,35 +190,38 @@ space.wrap("list deletion index out of range")) return space.w_None - def delitem__List_Slice(space, w_list, w_slice): start, stop, step, slicelength = w_slice.indices4(space, len(w_list.wrappeditems)) - _delitem_slice_helper(space, w_list, start, step, slicelength) -def _delitem_slice_helper(space, w_list, start, step, slicelength): if slicelength==0: return if step < 0: start = start + step * (slicelength-1) step = -step + # stop is invalid if step == 1: - assert start >= 0 - assert slicelength >= 0 - del w_list.wrappeditems[start:start+slicelength] + _del_slice(w_list, start, start+slicelength) else: items = w_list.wrappeditems n = len(items) + + recycle = [None] * slicelength i = start + # keep a reference to the objects to be removed, + # preventing side effects during destruction + recycle[0] = items[i] + for discard in range(1, slicelength): j = i+1 i += step while j < i: items[j-discard] = items[j] j += 1 + recycle[discard] = items[i] j = i+1 while j < n: @@ -250,7 +229,13 @@ j += 1 start = n - slicelength assert start >= 0 # annotator hint + # XXX allow negative indices in rlist del items[start:] + # now we can destruct recycle safely, regardless of + # side-effects to the list + del recycle[:] + + return space.w_None def setitem__List_ANY_ANY(space, w_list, w_index, w_any): idx = get_list_index(space, w_index) @@ -261,25 +246,23 @@ space.wrap("list index out of range")) return space.w_None +def setitem__List_Slice_List(space, w_list, w_slice, w_list2): + l = w_list2.wrappeditems + return _setitem_slice_helper(space, w_list, w_slice, l, len(l)) + def setitem__List_Slice_ANY(space, w_list, w_slice, w_iterable): + l = space.unpackiterable(w_iterable) + return _setitem_slice_helper(space, w_list, w_slice, l, len(l)) + +def _setitem_slice_helper(space, w_list, w_slice, sequence2, len2): oldsize = len(w_list.wrappeditems) start, stop, step, slicelength = w_slice.indices4(space, oldsize) - _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable) - -def _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable): - if isinstance(w_iterable, W_ListObject): - sequence2 = w_iterable.wrappeditems - else: - sequence2 = space.unpackiterable(w_iterable) - assert slicelength >= 0 items = w_list.wrappeditems - oldsize = len(items) - len2 = len(sequence2) + if step == 1: # Support list resizing for non-extended slices - delta = slicelength - len2 - if delta < 0: - delta = -delta + delta = len2 - slicelength + if delta >= 0: newsize = oldsize + delta # XXX support this in rlist! items += [None] * delta @@ -288,10 +271,9 @@ while i >= lim: items[i] = items[i-delta] i -= 1 - elif start >= 0: - del items[start:start+delta] else: - assert delta==0 + # shrinking requires the careful memory management of _del_slice() + _del_slice(w_list, start, start-delta) elif len2 != slicelength: # No resize for extended slices raise OperationError(space.w_ValueError, space.wrap("attempt to " "assign sequence of size %d to extended slice of size %d" % @@ -308,13 +290,14 @@ items[start] = sequence2[i] start -= step i -= 1 - return + return space.w_None else: # Make a shallow copy to more easily handle the reversal case sequence2 = list(sequence2) for i in range(len2): items[start] = sequence2[i] start += step + return space.w_None app = gateway.applevel(""" def listrepr(currently_in_repr, l): @@ -367,6 +350,26 @@ w_list.wrappeditems += space.unpackiterable(w_any) return space.w_None +def _del_slice(w_list, ilow, ihigh): + """ similar to the deletion part of list_ass_slice in CPython """ + items = w_list.wrappeditems + n = len(items) + if ilow < 0: + ilow = 0 + elif ilow > n: + ilow = n + if ihigh < ilow: + ihigh = ilow + elif ihigh > n: + ihigh = n + # keep a reference to the objects to be removed, + # preventing side effects during destruction + recycle = items[ilow:ihigh] + del items[ilow:ihigh] + # now we can destruct recycle safely, regardless of + # side-effects to the list + del recycle[:] + # note that the default value will come back wrapped!!! def list_pop__List_ANY(space, w_list, w_idx=-1): items = w_list.wrappeditems Modified: pypy/branch/2.5-merge/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/objspace.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/objspace.py Fri Oct 10 18:26:04 2008 @@ -764,6 +764,33 @@ else: return ObjSpace.call_method(self, w_obj, methname, *arg_w) + # support for the deprecated __getslice__, __setslice__, __delslice__ + + def getslice(self, w_obj, w_start, w_stop): + w_descr = self.lookup(w_obj, '__getslice__') + if w_descr is not None: + w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) + return self.get_and_call_function(w_descr, w_obj, w_start, w_stop) + else: + return ObjSpace.getslice(self, w_obj, w_start, w_stop) + + def setslice(self, w_obj, w_start, w_stop, w_sequence): + w_descr = self.lookup(w_obj, '__setslice__') + if w_descr is not None: + w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) + self.get_and_call_function(w_descr, w_obj, w_start, w_stop, + w_sequence) + else: + ObjSpace.setslice(self, w_obj, w_start, w_stop, w_sequence) + + def delslice(self, w_obj, w_start, w_stop): + w_descr = self.lookup(w_obj, '__delslice__') + if w_descr is not None: + w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) + self.get_and_call_function(w_descr, w_obj, w_start, w_stop) + else: + ObjSpace.delslice(self, w_obj, w_start, w_stop) + def raise_key_error(self, w_key): e = self.call_function(self.w_KeyError, w_key) raise OperationError(self.w_KeyError, e) @@ -793,3 +820,32 @@ del mm pow.extras['defaults'] = (None,) + + +# what is the maximum value slices can get on CPython? +# we need to stick to that value, because fake.py etc. +class Temp: + def __getslice__(self, i, j): + return j +slice_max = Temp()[:] +del Temp + + +def old_slice_range(space, w_obj, w_start, w_stop): + """Only for backward compatibility for __getslice__()&co methods.""" + if space.is_w(w_start, space.w_None): + w_start = space.wrap(0) + else: + w_start = space.wrap(space.getindex_w(w_start, None)) + if space.is_true(space.lt(w_start, space.wrap(0))): + w_start = space.add(w_start, space.len(w_obj)) + # NB. the language ref is inconsistent with the new-style class + # behavior when w_obj doesn't implement __len__(), so we just + # ignore this case. + if space.is_w(w_stop, space.w_None): + w_stop = space.wrap(slice_max) + else: + w_stop = space.wrap(space.getindex_w(w_stop, None)) + if space.is_true(space.lt(w_stop, space.wrap(0))): + w_stop = space.add(w_stop, space.len(w_obj)) + return w_start, w_stop Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_builtinshortcut.py Fri Oct 10 18:26:04 2008 @@ -1,6 +1,5 @@ from pypy.objspace.std.test import test_userobject from pypy.objspace.std.test import test_set -from pypy.objspace.std.test import test_stringobject WITH_BUILTINSHORTCUT = {'objspace.std.builtinshortcut': True} @@ -39,8 +38,3 @@ def setup_class(cls): from pypy import conftest cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) - -class AppTestString(test_stringobject.AppTestStringObject): - def setup_class(cls): - from pypy import conftest - cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_listmultiobject.py Fri Oct 10 18:26:04 2008 @@ -39,15 +39,6 @@ # These few here ^ would have failed before, but for good coverage, # all the list methods etc. should be tested also... - def test___getslice__(self): - skip("don't care for now") - - def test___setslice__(self): - skip("don't care for now") - - def test___delslice__(self): - skip("don't care for now") - class AppTest_ListMultiObject(BaseAppTest_ListMultiObject): def setup_class(cls): BaseAppTest_ListMultiObject.setup_class(cls) Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_listobject.py Fri Oct 10 18:26:04 2008 @@ -754,18 +754,3 @@ A() while lst: keepalive.append(lst[:]) - - def test___getslice__(self): - l = [1,2,3,4] - res = l.__getslice__(0, 2) - assert res == [1, 2] - - def test___setslice__(self): - l = [1,2,3,4] - l.__setslice__(0, 2, [5, 6]) - assert l == [5, 6, 3, 4] - - def test___delslice__(self): - l = [1,2,3,4] - l.__delslice__(0, 2) - assert l == [3, 4] Modified: pypy/branch/2.5-merge/pypy/objspace/thunk.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/thunk.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/thunk.py Fri Oct 10 18:26:04 2008 @@ -193,13 +193,6 @@ w2 = force(space, w2) w3 = force(space, w3) return parentfn(w1, w2, w3, *extra) - elif nb_args == 4: - def proxy(w1, w2, w3, w4, *extra): - w1 = force(space, w1) - w2 = force(space, w2) - w3 = force(space, w3) - w4 = force(space, w4) - return parentfn(w1, w2, w3, w4, *extra) else: raise NotImplementedError("operation %r has arity %d" % (opname, nb_args)) From arigo at codespeak.net Fri Oct 10 18:27:57 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 18:27:57 +0200 (CEST) Subject: [pypy-svn] r58922 - pypy/branch/getslice Message-ID: <20081010162757.2A91C16A0FC@codespeak.net> Author: arigo Date: Fri Oct 10 18:27:56 2008 New Revision: 58922 Added: pypy/branch/getslice/ - copied from r58921, pypy/branch/2.5-merge/ Log: Make a branch for playing with __getslice__. From xoraxax at codespeak.net Fri Oct 10 18:33:19 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 10 Oct 2008 18:33:19 +0200 (CEST) Subject: [pypy-svn] r58923 - in pypy/dist/pypy/rlib: . test Message-ID: <20081010163319.7B53E169F9D@codespeak.net> Author: xoraxax Date: Fri Oct 10 18:33:19 2008 New Revision: 58923 Modified: pypy/dist/pypy/rlib/test/test_timer.py pypy/dist/pypy/rlib/timer.py Log: Do not freeze timer values. Modified: pypy/dist/pypy/rlib/test/test_timer.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_timer.py (original) +++ pypy/dist/pypy/rlib/test/test_timer.py Fri Oct 10 18:33:19 2008 @@ -2,8 +2,13 @@ from pypy.translator.c.test.test_genc import compile from pypy.annotation.policy import AnnotatorPolicy + +t = Timer() +t.start("testc") +t.stop("testc") + def timer_user(): - t = Timer() + assert "testc" not in t.timingorder t.start("testa") t.stop("testa") t.start("testb") @@ -12,9 +17,10 @@ t.stop("testb") t.dump() + def test_compile_timer(): policy = AnnotatorPolicy() policy.allow_someobjects = False f_compiled = compile(timer_user, [], annotatorpolicy=policy) - f_compiled(expected_extra_mallocs=0) + f_compiled(expected_extra_mallocs=2) Modified: pypy/dist/pypy/rlib/timer.py ============================================================================== --- pypy/dist/pypy/rlib/timer.py (original) +++ pypy/dist/pypy/rlib/timer.py Fri Oct 10 18:33:19 2008 @@ -11,10 +11,16 @@ class Timer: def __init__(self): + self.reset() + + def reset(self): self.timings = {} self.levels = {} self.timingorder = [] + def _freeze_(self): + self.reset() + def start(self, timer): level = self.levels.setdefault(timer, -1) new_level = level + 1 From fijal at codespeak.net Fri Oct 10 18:40:58 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 18:40:58 +0200 (CEST) Subject: [pypy-svn] r58924 - pypy/branch/cbuild-refactor/pypy/translator Message-ID: <20081010164058.DF09A16A118@codespeak.net> Author: fijal Date: Fri Oct 10 18:40:58 2008 New Revision: 58924 Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py Log: (fijal, pedronis) Don't let driver go into your way when looking for exception Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/driver.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/driver.py Fri Oct 10 18:40:58 2008 @@ -276,7 +276,12 @@ self.proceed('compile') assert False, 'we should not get here' finally: - self.timer.end_event(goal) + try: + self.timer.end_event(goal) + except (KeyboardInterrupt, SystemExit): + raise + except: + pass return res def task_annotate(self): From hpk at codespeak.net Fri Oct 10 18:57:14 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 10 Oct 2008 18:57:14 +0200 (CEST) Subject: [pypy-svn] r58925 - in pypy/build/benchmem: . testing Message-ID: <20081010165714.C779816A0E9@codespeak.net> Author: hpk Date: Fri Oct 10 18:57:14 2008 New Revision: 58925 Modified: pypy/build/benchmem/report.py pypy/build/benchmem/runbench.py pypy/build/benchmem/testing/test_benchtool.py Log: (xoraxax, hpk) refactor benchmarking parsing, resultset handling, preparing different types of benchmarks Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Fri Oct 10 18:57:14 2008 @@ -31,10 +31,10 @@ return "\n".join(lines) -def maxtable_overview(reader): +def maxtable_overview(resultset): tw = py.io.TerminalWriter() - for name, results in reader.name2results.items(): + for name, results in resultset.getname2results(): tw.sep("=", name) row0 = "executable maxprivate maxrss".split() rows = [row0] @@ -46,14 +46,14 @@ tw.line(asciitable(rows)) class TableReporter: - def __init__(self, reader): - self.reader = reader + def __init__(self, resultset): + self.resultset = resultset begin = report = end = lambda x: None # hooks def run(self): self.begin() - for name, results in reader.name2results.items(): + for name, results in resultset.getname2results(): row0 = ["num"] + [result.executable for result in results] numsnapshots = min([len(i.snapshots) for i in results]) @@ -107,25 +107,13 @@ ) os.system("gnuplot gnuplotcmd") -class Sorter: - def __init__(self, name2results): - self.name2results = name2results - - def filter(self, benchprefix=""): - d = {} - for name, results in self.name2results.iteritems(): - if name.startswith(benchprefix): - d[name] = results - return Sorter(d) - - def getsorted(self): - l = self.name2results.items() - l.sort() - return l +class IncrementalSizePerBench: + def __init__(self, resultset): + self.resultset = resultset.filter(benchtype="sizes") def getexecutables(self): ret = None - for name, results in self.name2results.iteritems(): + for name, results in self.resultset.getname2results(): executables = [result.executable for result in results] if ret is None: ret = executables @@ -133,20 +121,18 @@ raise ValueError("resultset has incompatible list of executables" "%s != %s" %(ret, executables)) return ret - -class IncrementalSizePerBench: - def __init__(self, reader): - self.reader = reader def run(self): tw = py.io.TerminalWriter() tw.sep("=", "Incremental private RSS of size benchmarks") - sorter = Sorter(self.reader.name2results) - sorter = sorter.filter(benchprefix="sizes.") - executables = sorter.getexecutables() + + executables = self.getexecutables() row0 = ["name"] + [str(x) for x in executables] rows = [row0] - for name, results in sorter.getsorted(): + name2results = self.resultset.getname2results() + name2results.sort() + + for name, results in name2results: basesize = self.get_incremental_size(results[0]) row = [name] for result in results: @@ -167,12 +153,14 @@ return inbench - basesize class BaseSizeOfInterpreters: - def __init__(self, reader): - self.reader = reader + def __init__(self, resultset): + self.resultset = resultset.filter(benchtype="basesize") + def run(self): + XXX tw = py.io.TerminalWriter() tw.sep("=", "Base Size of interpreters (using sizes.bench_list_of_None)") - sorter = Sorter(self.reader.name2results).filter(benchprefix="sizes.") + sorter = Sorter(self.reader.name2results).filter(benchprefix="bench_list_of_None") row0 = "executable rss shared_clean shared_dirty private_clean private_dirty".split() rows = [row0] for result in sorter.name2results['sizes.bench_list_of_None']: @@ -186,16 +174,16 @@ options, args = parser.parse_args() benchlog = py.path.local(options.benchlog) - reader = runbench.LogReader() - reader.parse(benchlog) + resultset = runbench.ResultSet() + resultset.parse(benchlog) #maxtable_overview(reader) - CheckpointDetails(reader).run() - IncrementalSizePerBench(reader).run() - BaseSizeOfInterpreters(reader).run() + CheckpointDetails(resultset).run() + IncrementalSizePerBench(resultset).run() + #BaseSizeOfInterpreters(resultset).run() if options.gnuplot: - Gnuplot(reader).run() + Gnuplot(resultset).run() #for name, results in reader.name2results.items(): # tw.sep("=", name) Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Fri Oct 10 18:57:14 2008 @@ -59,10 +59,12 @@ def write_benchheader(self, benchname, args): print >>self.logstream, self.SEPBENCH - print >>self.logstream, "#executable=%r" %(str(self.executable ),) - print >>self.logstream, "#benchpath=%r" %(self.benchpath.basename,) - print >>self.logstream, "#benchname=%r" %(benchname,) - print >>self.logstream, "#benchargs=%r" %(args,) + print >>self.logstream, "#benchtype=sizes" + print >>self.logstream, "#executable=%s" %(str(self.executable ),) + print >>self.logstream, "#benchpath=%s" %(self.benchpath.basename,) + print >>self.logstream, "#benchname=%s" %(benchname,) + print >>self.logstream, "#benchargs=%s" %(args,) + print >>self.logstream def getnames(self): l = [] @@ -107,23 +109,40 @@ # ================ reading a benchmark log file ======================= # -class LogReader(object): - def __init__(self): - self.name2results = {} +class ResultSet(object): + def __init__(self, results=None): + if results is None: + results = [] + self.results = results + + def getname2results(self): + name2results = {} + for result in self.results: + l = name2results.setdefault(result.benchname, []) + l.append(result) + return name2results.items() + + def filter(self, benchtype): + l = [] + for result in self.results: + if benchtype == None or result.benchtype == benchtype: + l.append(result) + return ResultSet(l) def parse(self, logpath): f = logpath.open() for result in BenchmarkResult.parse(f): #print "parsed", result - l = self.name2results.setdefault(result.benchname, []) - l.append(result) + self.results.append(result) f.close() class BenchmarkResult: - def __init__(self, snapshots, executable, benchname, benchargs): + benchtype = "sizes" + def __init__(self, snapshots, executable, benchpath, benchname, benchargs): assert snapshots self.snapshots = snapshots self.executable = executable + self.benchpath = benchpath self.benchname = benchname self.benchargs = benchargs @@ -134,37 +153,55 @@ return maxvalue @classmethod + def parseheader(cls, iterline): + kw = {} + while 1: + lineno, line = iterline() + if not line.strip(): + return kw + assert line.startswith("#"), line + key, value = map(str.strip, line[1:].split("=")) + kw[key] = value + + @classmethod def parse(cls, f): + def genline(): + lineno = 1 + while 1: + yield lineno, f.readline() + lineno += 1 + iterline = genline().next + lineno, line = iterline() while not f.closed: - line = f.readline() - if not line.strip(): + if not line: break - if not line.startswith("#executable"): - if line != BenchRunner.SEPBENCH: - print "ignoring", line + line = line.rstrip() + if line != BenchRunner.SEPBENCH: + print "ignoring %d: %s" %(lineno, line) + lineno, line = iterline() continue - # see write_benchheader - executable = eval(line.split("=", 1)[1]) - benchbasename = eval(f.readline().split("=", 1)[1]) - benchfuncname = eval(f.readline().split("=", 1)[1]) - benchname = "%s.%s" % (benchbasename[:-3], benchfuncname) - benchargs = eval(f.readline().split("=", 1)[1]) - - snapshots = [] - line = f.readline() - while 1: - mappings = [] - while line != smaps.SmapsRecorder.SEPSNAPSHOT: - mappings.append(smaps.Mapping(line)) - line = f.readline() - #print "reading", line.strip() - snapshots.append(Snapshot(mappings)) - line = f.readline() - #print "reading", line.strip() - if not line or line.startswith(BenchRunner.SEPBENCH): - break - yield BenchmarkResult(snapshots, executable=executable, - benchname=benchname, benchargs=benchargs) + kw = cls.parseheader(iterline) + + benchtype = kw.pop('benchtype') + if benchtype == "sizes": + snapshots = [] + lineno, line = iterline() + while 1: + mappings = [] + while line != smaps.SmapsRecorder.SEPSNAPSHOT: + mappings.append(smaps.Mapping(line)) + lineno, line = iterline() + #print "reading", line.strip() + snapshots.append(Snapshot(mappings)) + lineno, line = iterline() + print "reading %d: %s" %(lineno, line) + if not line or line.startswith(BenchRunner.SEPBENCH): + break + print "yielding result", kw['benchname'] + yield BenchmarkResult(snapshots, **kw) + else: + assert 0, benchtype + print "end" def _verify_integrity(self): for snap in self.snapshots: Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Fri Oct 10 18:57:14 2008 @@ -30,12 +30,12 @@ runner = runbench.BenchRunnerSizes("python2.5", "sizes.py", benchlog, options) assert runner.benchpath.basename == "sizes.py" runner.run() - benchresult = runbench.LogReader() - benchresult.parse(benchlog) + resultset = runbench.ResultSet() + resultset.parse(benchlog) names = runner.getnames() - assert len(benchresult.name2results) == len(names) - for results in benchresult.name2results.values(): + assert len(resultset.getname2results()) == len(names) + for name, results in resultset.getname2results(): assert len(results) ==1 assert len(results[0].snapshots) == 2 + 1 From hpk at codespeak.net Fri Oct 10 19:07:30 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 10 Oct 2008 19:07:30 +0200 (CEST) Subject: [pypy-svn] r58927 - in pypy/build/benchmem: . testing Message-ID: <20081010170730.A194A16A0EF@codespeak.net> Author: hpk Date: Fri Oct 10 19:07:30 2008 New Revision: 58927 Modified: pypy/build/benchmem/runbench.py pypy/build/benchmem/testing/test_benchtool.py Log: (xoraxax,hpk) specialize names for objsize benchmarks Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Fri Oct 10 19:07:30 2008 @@ -16,7 +16,7 @@ class BenchRunner: SEPBENCH = "=" * 80 -class BenchRunnerSizes(BenchRunner): +class BenchRunnerObjsize(BenchRunner): def __init__(self, executable, fsname, logpath, options): self.executable = executable self.benchpath = benchmarkdir.join(fsname) @@ -131,27 +131,12 @@ def parse(self, logpath): f = logpath.open() - for result in BenchmarkResult.parse(f): + for result in Result.parse(f): #print "parsed", result self.results.append(result) f.close() - -class BenchmarkResult: - benchtype = "sizes" - def __init__(self, snapshots, executable, benchpath, benchname, benchargs): - assert snapshots - self.snapshots = snapshots - self.executable = executable - self.benchpath = benchpath - self.benchname = benchname - self.benchargs = benchargs - - def max(self, attrname): - maxvalue = 0 - for snap in self.snapshots: - maxvalue = max(maxvalue, getattr(snap, attrname)) - return maxvalue - + +class Result(object): @classmethod def parseheader(cls, iterline): kw = {} @@ -194,14 +179,29 @@ #print "reading", line.strip() snapshots.append(Snapshot(mappings)) lineno, line = iterline() - print "reading %d: %s" %(lineno, line) + #print "reading %d: %s" %(lineno, line) if not line or line.startswith(BenchRunner.SEPBENCH): break - print "yielding result", kw['benchname'] - yield BenchmarkResult(snapshots, **kw) + #print "yielding result", kw['benchname'] + yield ObjsizeResult(snapshots, **kw) else: assert 0, benchtype - print "end" + +class ObjsizeResult(Result): + benchtype = "sizes" + def __init__(self, snapshots, executable, benchpath, benchname, benchargs): + assert snapshots + self.snapshots = snapshots + self.executable = executable + self.benchpath = benchpath + self.benchname = benchname + self.benchargs = benchargs + + def max(self, attrname): + maxvalue = 0 + for snap in self.snapshots: + maxvalue = max(maxvalue, getattr(snap, attrname)) + return maxvalue def _verify_integrity(self): for snap in self.snapshots: @@ -267,7 +267,7 @@ def getrunnerclass(fsname): if fsname == "sizes.py": - return BenchRunnerSizes + return BenchRunnerObjsize if __name__ == '__main__': (options, args) = parser.parse_args() Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Fri Oct 10 19:07:30 2008 @@ -27,7 +27,7 @@ benchlog=tmpdir.join("log") class options: numiter = 10 - runner = runbench.BenchRunnerSizes("python2.5", "sizes.py", benchlog, options) + runner = runbench.BenchRunnerObjsize("python2.5", "sizes.py", benchlog, options) assert runner.benchpath.basename == "sizes.py" runner.run() resultset = runbench.ResultSet() From iko at codespeak.net Fri Oct 10 19:31:13 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 10 Oct 2008 19:31:13 +0200 (CEST) Subject: [pypy-svn] r58928 - in pypy/branch/2.5-merge/pypy/objspace/std: . test Message-ID: <20081010173113.E707316A151@codespeak.net> Author: iko Date: Fri Oct 10 19:31:12 2008 New Revision: 58928 Modified: pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py pypy/branch/2.5-merge/pypy/objspace/std/test/test_stringobject.py Log: (iko, cfbolz) raise OverflowError on replace when the result is too large Modified: pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py Fri Oct 10 19:31:12 2008 @@ -260,16 +260,9 @@ return space.newlist(res_w) - -def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): - maxsplit = space.int_w(w_maxsplit) +def _split_helper(space, value, sep, maxsplit): res_w = [] start = 0 - value = w_self._value - by = w_by._value - bylen = len(by) - if bylen == 0: - raise OperationError(space.w_ValueError, space.wrap("empty separator")) while maxsplit != 0: next = value.find(by, start) @@ -278,9 +271,18 @@ res_w.append(sliced(space, value, start, next)) start = next + bylen maxsplit -= 1 # NB. if it's already < 0, it stays < 0 - + res_w.append(sliced(space, value, start, len(value))) +def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): + maxsplit = space.int_w(w_maxsplit) + value = w_self._value + by = w_by._value + bylen = len(by) + if bylen == 0: + raise OperationError(space.w_ValueError, space.wrap("empty separator")) + + res_w = _split_helper(space, value, by, maxsplit) return space.newlist(res_w) def str_rsplit__String_None_ANY(space, w_self, w_none, w_maxsplit=-1): @@ -485,22 +487,24 @@ if maxsplit > 0 and maxsplit < upper + 2: upper = maxsplit - 1 assert upper >= 0 - substrings = [""] + substrings_w = [""] for i in range(upper): c = input[i] - substrings.append(c) - substrings.append(input[upper:]) - return space.wrap(by.join(substrings)) - startidx = 0 - substrings = [] - foundidx = input.find(sub, startidx) - while foundidx >= 0 and maxsplit != 0: - substrings.append(input[startidx:foundidx]) - startidx = foundidx + len(sub) - foundidx = input.find(sub, startidx) - maxsplit = maxsplit - 1 - substrings.append(input[startidx:]) - return space.wrap(by.join(substrings)) + substrings_w.append(c) + substrings_w.append(input[upper:]) + else: + substrings_w = _split_helper(space, input, sub, maxsplit) + + try: + # XXX conservative estimate. If your strings are that close + # to overflowing, bad luck. + ovfcheck(len(substrings_w) * len(by) + len(input)) + except OverflowError: + raise OperationError( + space.w_OverflowError, + space.wrap("replace string is too long")) + + return space.wrap(by.join(substrings_w)) def _strip(space, w_self, w_chars, left, right): "internal function called by str_xstrip methods" Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_stringobject.py Fri Oct 10 19:31:12 2008 @@ -714,6 +714,13 @@ assert x.rstrip(y) == '' assert x.lstrip(y) == '' + def test_replace_overflow(self): + import sys + if sys.maxint > 2**31-1: + skip("Wrong platform") + s = "a" * (2**16) + raises(OverflowError, s.replace, "", s) + class AppTestPrebuilt(AppTestStringObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True}) From fijal at codespeak.net Fri Oct 10 19:33:42 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 10 Oct 2008 19:33:42 +0200 (CEST) Subject: [pypy-svn] r58929 - in pypy/branch/cbuild-refactor/pypy: config translator translator/c translator/platform translator/platform/test translator/tool Message-ID: <20081010173342.BB39016A169@codespeak.net> Author: fijal Date: Fri Oct 10 19:33:42 2008 New Revision: 58929 Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py (contents, props changed) Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/driver.py pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Log: (pedronis, fijal) Shave two yaks in order to gradually remove cbuild.py as it is. Moved profopt to genc and some other things. Completely disable cbuild.CCompiler for now. Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/config/translationoption.py (original) +++ pypy/branch/cbuild-refactor/pypy/config/translationoption.py Fri Oct 10 19:33:42 2008 @@ -352,16 +352,6 @@ 'maemo', ] -def set_platform(config, platform): - from pypy.rlib.pyplatform import Platform, Maemo - from pypy.rlib import pyplatform - from pypy.translator.tool.cbuild import ExternalCompilationInfo - if isinstance(platform, str): - if platform == 'maemo': - platform = Maemo(cc=config.translation.cc or None) - elif platform == 'host': - return - else: - raise NotImplementedError('Platform = %s' % (platform,)) - assert isinstance(platform, Platform) - pyplatform.platform = platform +def get_platform(config): + from pypy.translator.platform import host + return host Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Fri Oct 10 19:33:42 2008 @@ -7,8 +7,6 @@ from pypy.translator.llsupport.wrapper import new_wrapper from pypy.translator.gensupp import uniquemodulename, NameManager from pypy.translator.tool.cbuild import so_ext, ExternalCompilationInfo -from pypy.translator.tool.cbuild import compile_c_module -from pypy.translator.tool.cbuild import CCompiler, ProfOpt from pypy.translator.tool.cbuild import import_module_from_directory from pypy.translator.tool.cbuild import check_under_under_thread from pypy.rpython.lltypesystem import lltype @@ -18,6 +16,60 @@ from pypy.rpython.typesystem import getfunctionptr from pypy.translator.c import gc +class ProfOpt(object): + #XXX assuming gcc style flags for now + name = "profopt" + + def __init__(self, compiler): + self.compiler = compiler + + def first(self): + return self.build('-fprofile-generate') + + def probe(self, exe, args): + # 'args' is a single string typically containing spaces + # and quotes, which represents several arguments. + self.compiler.platform.execute(exe, args) + + def after(self): + return self.build('-fprofile-use') + + def build(self, option): + eci = ExternalCompilationInfo(compile_extra=[option], + link_extra=[option]) + # XXX + #compiler.fix_gcc_random_seed = True + return self.compiler._build(eci) + +class CCompilerDriver(object): + def __init__(self, platform, cfiles, eci, outputfilename=None, + profbased=False): + self.platform = platform + self.cfiles = cfiles + self.eci = eci + self.outputfilename = outputfilename + self.profbased = profbased + + def _build(self, eci=ExternalCompilationInfo()): + return self.platform.compile(self.cfiles, self.eci.merge(eci), + outputfilename=self.outputfilename) + + def build(self): + if self.profbased: + return self._do_profbased() + return self._build() + + def _do_profbased(self): + ProfDriver, args = self.profbased + profdrv = ProfDriver(self) + dolog = getattr(log, profdrv.name) + dolog(args) + exename = profdrv.first() + dolog('Gathering profile data from: %s %s' % ( + str(exename), args)) + profdrv.probe(exename, args) + return profdrv.after() + class CBuilder(object): c_source_filename = None _compiled = False @@ -132,7 +184,7 @@ if self.config.translation.sandbox: defines['RPY_SANDBOXED'] = 1 if CBuilder.have___thread is None: - CBuilder.have___thread = check_under_under_thread() + CBuilder.have___thread = self.translator.platform.check___thread() if not self.standalone: assert not self.config.translation.instrument cfile, extra = gen_source(db, modulename, targetdir, self.eci, @@ -330,19 +382,20 @@ def compile(self): assert self.c_source_filename assert not self._compiled - compiler = self.getccompiler() + compiler = CCompilerDriver(self.translator.platform, + [self.c_source_filename] + self.extrafiles, + self.eci, profbased=self.getprofbased()) if self.config.translation.gcrootfinder == "asmgcc": + xxx # as we are gcc-only anyway, let's just use the Makefile. cmdline = "make -C '%s'" % (self.targetdir,) err = os.system(cmdline) if err != 0: raise OSError("failed (see output): " + cmdline) else: - eci = self.eci.merge(ExternalCompilationInfo(includes= - [str(self.targetdir)])) - self.adaptflags(compiler) - compiler.build() - self.executable_name = str(compiler.outputfilename) + #self.adaptflags(compiler) + self.executable_name = compiler.build() + assert self.executable_name self._compiled = True return self.executable_name @@ -361,6 +414,7 @@ compiler.link_extra.append(self.config.translation.linkerflags) def gen_makefile(self, targetdir): + return # XXX def write_list(lst, prefix): for i, fn in enumerate(lst): print >> f, prefix, fn, Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/driver.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/driver.py Fri Oct 10 19:33:42 2008 @@ -53,13 +53,12 @@ self.compiler = compiler def first(self): - self.compiler._build() + return self.compiler._build() def probe(self, exe, args): - from py.compat import subprocess env = os.environ.copy() env['_INSTRUMENT_COUNTERS'] = str(self.datafile) - subprocess.call("'%s' %s" % (exe, args), env=env, shell=True) + self.compiler.platform.execute(exe, args, env=env) def after(self): # xxx Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Fri Oct 10 19:33:42 2008 @@ -16,6 +16,9 @@ self.out = out self.err = err + def __repr__(self): + return "" % (self.returncode,) + class Platform(object): def __init__(self, cc): self.cc = cc @@ -23,12 +26,15 @@ def compile(self, cfiles, eci, outputfilename=None, standalone=True): raise NotImplementedError("Pure abstract baseclass") - def execute(self, file_to_exec): + def execute(self, file_to_exec, args=None, env=None): raise NotImplementedError("Pure abstract baseclass") def __repr__(self): return '<%s cc=%s>' % (self.__class__.__name__, self.cc) + def check___thread(self): + return True + if sys.platform == 'linux2': from pypy.translator.platform.linux import Linux host = Linux() Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Fri Oct 10 19:33:42 2008 @@ -7,9 +7,17 @@ log = py.log.Producer("cbuild") py.log.setconsumer("cbuild", ansi_log) -def _run_subprocess(args): - pipe = Popen(args, executable=args[0], - stdout=PIPE, stderr=PIPE, shell=False) +def _run_subprocess(executable, args, env=None): + if isinstance(args, str): + args = str(executable) + ' ' + args + shell = True + else: + if args is None: + args = [str(executable)] + else: + args = [str(executable)] + args + shell = False + pipe = Popen(args, stdout=PIPE, stderr=PIPE, shell=shell, env=env) stdout, stderr = pipe.communicate() return pipe.returncode, stdout, stderr @@ -42,9 +50,8 @@ args += ['-o', str(exe_name)] if not standalone: args = self._args_for_shared(args) - args = [self.cc] + args - log.execute(' '.join(args)) - returncode, stdout, stderr = _run_subprocess(args) + log.execute(self.cc + ' ' + ' '.join(args)) + returncode, stdout, stderr = _run_subprocess(self.cc, args) if returncode != 0: errorfile = exe_name.new(ext='errors') errorfile.write(stderr) @@ -56,6 +63,7 @@ raise CompilationError(stdout, stderr) return exe_name - def execute(self, executable): - returncode, stdout, stderr = _run_subprocess([str(executable)]) + def execute(self, executable, args=None, env=None): + returncode, stdout, stderr = _run_subprocess(str(executable), args, + env) return ExecutionResult(returncode, stdout, stderr) Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Fri Oct 10 19:33:42 2008 @@ -0,0 +1,9 @@ + +from pypy.translator.platform import host, CompilationError + +def test_echo(): + res = host.execute('echo', '42 24') + assert res.out == '42 24\n' + res = host.execute('echo', ['42', '24']) + assert res.out == '42 24\n' + Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Fri Oct 10 19:33:42 2008 @@ -341,35 +341,6 @@ return spawn_and_log -class ProfOpt(object): - #XXX assuming gcc style flags for now - name = "profopt" - - def __init__(self, compiler): - self.compiler = compiler - - def first(self): - self.build('-fprofile-generate') - - def probe(self, exe, args): - # 'args' is a single string typically containing spaces - # and quotes, which represents several arguments. - os.system("'%s' %s" % (exe, args)) - - def after(self): - self.build('-fprofile-use') - - def build(self, option): - compiler = self.compiler - compiler.fix_gcc_random_seed = True - compiler.compile_extra.append(option) - compiler.link_extra.append(option) - try: - compiler._build() - finally: - compiler.compile_extra.pop() - compiler.link_extra.pop() - class CompilationError(Exception): pass @@ -378,6 +349,7 @@ def __init__(self, cfilenames, eci, outputfilename=None, compiler_exe=None, profbased=None, standalone=True): + XXX self.cfilenames = cfilenames if standalone: ext = '' From arigo at codespeak.net Fri Oct 10 19:38:46 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 19:38:46 +0200 (CEST) Subject: [pypy-svn] r58930 - in pypy/branch/getslice/pypy: annotation annotation/test interpreter objspace objspace/flow objspace/std objspace/std/test rpython rpython/lltypesystem rpython/ootypesystem rpython/test translator Message-ID: <20081010173846.72EB716A0C0@codespeak.net> Author: arigo Date: Fri Oct 10 19:38:43 2008 New Revision: 58930 Removed: pypy/branch/getslice/pypy/rpython/lltypesystem/rslice.py pypy/branch/getslice/pypy/rpython/ootypesystem/rslice.py pypy/branch/getslice/pypy/rpython/rslice.py Modified: pypy/branch/getslice/pypy/annotation/annrpython.py pypy/branch/getslice/pypy/annotation/binaryop.py pypy/branch/getslice/pypy/annotation/bookkeeper.py pypy/branch/getslice/pypy/annotation/builtin.py pypy/branch/getslice/pypy/annotation/model.py pypy/branch/getslice/pypy/annotation/test/test_annrpython.py pypy/branch/getslice/pypy/annotation/unaryop.py pypy/branch/getslice/pypy/interpreter/baseobjspace.py pypy/branch/getslice/pypy/objspace/descroperation.py pypy/branch/getslice/pypy/objspace/flow/objspace.py pypy/branch/getslice/pypy/objspace/reflective.py pypy/branch/getslice/pypy/objspace/std/builtinshortcut.py pypy/branch/getslice/pypy/objspace/std/listobject.py pypy/branch/getslice/pypy/objspace/std/objspace.py pypy/branch/getslice/pypy/objspace/std/rangeobject.py pypy/branch/getslice/pypy/objspace/std/ropeobject.py pypy/branch/getslice/pypy/objspace/std/ropeunicodeobject.py pypy/branch/getslice/pypy/objspace/std/sliceobject.py pypy/branch/getslice/pypy/objspace/std/stringobject.py pypy/branch/getslice/pypy/objspace/std/strsliceobject.py pypy/branch/getslice/pypy/objspace/std/test/test_builtinshortcut.py pypy/branch/getslice/pypy/objspace/std/test/test_listmultiobject.py pypy/branch/getslice/pypy/objspace/std/test/test_listobject.py pypy/branch/getslice/pypy/objspace/std/test/test_rangeobject.py pypy/branch/getslice/pypy/objspace/std/test/test_stringobject.py pypy/branch/getslice/pypy/objspace/std/test/test_strsliceobject.py pypy/branch/getslice/pypy/objspace/std/test/test_tupleobject.py pypy/branch/getslice/pypy/objspace/std/test/test_unicodeobject.py pypy/branch/getslice/pypy/objspace/std/tupleobject.py pypy/branch/getslice/pypy/objspace/std/unicodeobject.py pypy/branch/getslice/pypy/objspace/thunk.py pypy/branch/getslice/pypy/rpython/lltypesystem/rlist.py pypy/branch/getslice/pypy/rpython/ootypesystem/rlist.py pypy/branch/getslice/pypy/rpython/rlist.py pypy/branch/getslice/pypy/rpython/rstr.py pypy/branch/getslice/pypy/rpython/rtuple.py pypy/branch/getslice/pypy/rpython/rtyper.py pypy/branch/getslice/pypy/rpython/test/test_rlist.py pypy/branch/getslice/pypy/translator/simplify.py pypy/branch/getslice/pypy/translator/transform.py Log: (antocuni, arigo) Probably in-progress. Modified: pypy/branch/getslice/pypy/annotation/annrpython.py ============================================================================== --- pypy/branch/getslice/pypy/annotation/annrpython.py (original) +++ pypy/branch/getslice/pypy/annotation/annrpython.py Fri Oct 10 19:38:43 2008 @@ -760,10 +760,6 @@ def consider_op_newdict(self): return self.bookkeeper.newdict() - def consider_op_newslice(self, start, stop, step): - self.bookkeeper.count('newslice', start, stop, step) - return annmodel.SomeSlice(start, stop, step) - def _registeroperations(cls, model): # All unary operations Modified: pypy/branch/getslice/pypy/annotation/binaryop.py ============================================================================== --- pypy/branch/getslice/pypy/annotation/binaryop.py (original) +++ pypy/branch/getslice/pypy/annotation/binaryop.py Fri Oct 10 19:38:43 2008 @@ -10,7 +10,7 @@ from pypy.annotation.model import SomeUnicodeCodePoint from pypy.annotation.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeIterator -from pypy.annotation.model import SomePBC, SomeSlice, SomeFloat, s_None +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 @@ -564,14 +564,6 @@ delitem.can_only_throw = _can_only_throw -class __extend__(pairtype(SomeSlice, SomeSlice)): - - def union((slic1, slic2)): - return SomeSlice(unioncheck(slic1.start, slic2.start), - unioncheck(slic1.stop, slic2.stop), - unioncheck(slic1.step, slic2.step)) - - class __extend__(pairtype(SomeTuple, SomeInteger)): def getitem((tup1, int2)): @@ -585,13 +577,6 @@ return unionof(*tup1.items) getitem.can_only_throw = [IndexError] -class __extend__(pairtype(SomeTuple, SomeSlice)): - - def getitem((tup, slic)): - start, stop, step = slic.constant_indices() - return SomeTuple(tup.items[start:stop:step]) - getitem.can_only_throw = [] - class __extend__(pairtype(SomeList, SomeInteger)): @@ -623,40 +608,6 @@ lst1.listdef.resize() delitem.can_only_throw = [IndexError] -def check_negative_slice(s_slice): - if isinstance(s_slice.start, SomeInteger) and not s_slice.start.nonneg: - raise TypeError("%s not proven to have non-negative start" % s_slice) - if isinstance(s_slice.stop, SomeInteger) and not s_slice.stop.nonneg and\ - getattr(s_slice.stop, 'const', 0) != -1: - raise TypeError("%s not proven to have non-negative stop" % s_slice) - -class __extend__(pairtype(SomeList, SomeSlice)): - - def getitem((lst, slic)): - check_negative_slice(slic) - return lst.listdef.offspring() - getitem.can_only_throw = [] - - def setitem((lst, slic), s_iterable): - check_negative_slice(slic) - # we need the same unifying effect as the extend() method for - # the case lst1[x:y] = lst2. - lst.method_extend(s_iterable) - setitem.can_only_throw = [] - - def delitem((lst1, slic)): - check_negative_slice(slic) - lst1.listdef.resize() - delitem.can_only_throw = [] - -class __extend__(pairtype(SomeString, SomeSlice), - pairtype(SomeUnicodeString, SomeSlice)): - - def getitem((str1, slic)): - check_negative_slice(slic) - return str1.basestringclass() - getitem.can_only_throw = [] - class __extend__(pairtype(SomeString, SomeInteger)): def getitem((str1, int2)): Modified: pypy/branch/getslice/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/branch/getslice/pypy/annotation/bookkeeper.py (original) +++ pypy/branch/getslice/pypy/annotation/bookkeeper.py Fri Oct 10 19:38:43 2008 @@ -68,9 +68,6 @@ def consider_generic(self, *args): return tuple([self.typerepr(x) for x in args]) - def consider_newslice(self, s_start, s_stop, s_step): - return ':'.join([self.indexrepr(s_start), self.indexrepr(s_stop), self.steprepr(s_step)]) - def consider_list_list_eq(self, obj1, obj2): return obj1, obj2 Modified: pypy/branch/getslice/pypy/annotation/builtin.py ============================================================================== --- pypy/branch/getslice/pypy/annotation/builtin.py (original) +++ pypy/branch/getslice/pypy/annotation/builtin.py Fri Oct 10 19:38:43 2008 @@ -4,7 +4,7 @@ import sys from pypy.annotation.model import SomeInteger, SomeObject, SomeChar, SomeBool -from pypy.annotation.model import SomeString, SomeTuple, SomeSlice, s_Bool +from pypy.annotation.model import SomeString, SomeTuple, s_Bool from pypy.annotation.model import SomeUnicodeCodePoint, SomeAddress from pypy.annotation.model import SomeFloat, unionof, SomeUnicodeString from pypy.annotation.model import SomePBC, SomeInstance, SomeDict @@ -249,19 +249,19 @@ getbookkeeper().warning("ignoring apply%r" % (stuff,)) return SomeObject() -def builtin_slice(*args): - bk = getbookkeeper() - if len(args) == 1: - return SomeSlice( - bk.immutablevalue(None), args[0], bk.immutablevalue(None)) - elif len(args) == 2: - return SomeSlice( - args[0], args[1], bk.immutablevalue(None)) - elif len(args) == 3: - return SomeSlice( - args[0], args[1], args[2]) - else: - raise Exception, "bogus call to slice()" +##def builtin_slice(*args): +## bk = getbookkeeper() +## if len(args) == 1: +## return SomeSlice( +## bk.immutablevalue(None), args[0], bk.immutablevalue(None)) +## elif len(args) == 2: +## return SomeSlice( +## args[0], args[1], bk.immutablevalue(None)) +## elif len(args) == 3: +## return SomeSlice( +## args[0], args[1], args[2]) +## else: +## raise Exception, "bogus call to slice()" def OSError_init(s_self, *args): Modified: pypy/branch/getslice/pypy/annotation/model.py ============================================================================== --- pypy/branch/getslice/pypy/annotation/model.py (original) +++ pypy/branch/getslice/pypy/annotation/model.py Fri Oct 10 19:38:43 2008 @@ -253,25 +253,6 @@ def can_be_none(self): return True -class SomeSlice(SomeObject): - knowntype = slice - immutable = True - def __init__(self, start, stop, step): - self.start = start - self.stop = stop - self.step = step - - def constant_indices(self): - if (self.start.is_immutable_constant() and - self.stop .is_immutable_constant() and - self.step .is_immutable_constant()): - return self.start.const, self.stop.const, self.step.const - else: - raise Exception("need constant indices for this slice") - - def can_be_none(self): - return False - class SomeTuple(SomeObject): "Stands for a tuple of known length." knowntype = tuple Modified: pypy/branch/getslice/pypy/annotation/test/test_annrpython.py ============================================================================== --- pypy/branch/getslice/pypy/annotation/test/test_annrpython.py (original) +++ pypy/branch/getslice/pypy/annotation/test/test_annrpython.py Fri Oct 10 19:38:43 2008 @@ -425,16 +425,6 @@ s_meth = s_example.getattr(iv(methname)) assert isinstance(s_constmeth, annmodel.SomeBuiltin) - def test_simple_slicing0(self): - a = self.RPythonAnnotator() - a.build_types(snippet.simple_slice, [list]) - g = graphof(a, snippet.simple_slice) - for block in g.iterblocks(): - for op in block.operations: - if op.opname == "newslice": - assert isinstance(a.binding(op.result), - annmodel.SomeSlice) - def test_simple_slicing(self): a = self.RPythonAnnotator() s = a.build_types(snippet.simple_slice, [list]) @@ -570,11 +560,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_slice_union(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.slice_union, [int]) - assert isinstance(s, annmodel.SomeSlice) - def test_bltin_code_frame_confusion(self): a = self.RPythonAnnotator() a.build_types(snippet.bltin_code_frame_confusion,[]) @@ -3040,6 +3025,28 @@ a.build_types(f, [str]) + def test_setslice(self): + def f(): + lst = [2, 5, 7] + lst[1:2] = [4] + return lst + + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeList) + assert not s.listdef.listitem.resized + + def test_delslice(self): + def f(): + lst = [2, 5, 7] + del lst[1:2] + return lst + + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeList) + assert s.listdef.listitem.resized + def test_listitem_no_mutating(self): from pypy.rlib.debug import check_annotation called = [] Modified: pypy/branch/getslice/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/getslice/pypy/annotation/unaryop.py (original) +++ pypy/branch/getslice/pypy/annotation/unaryop.py Fri Oct 10 19:38:43 2008 @@ -24,6 +24,7 @@ 'iter', 'next', 'invert', 'type', 'issubtype', 'pos', 'neg', 'nonzero', 'abs', 'hex', 'oct', 'ord', 'int', 'float', 'long', 'id', + 'getslice', 'setslice', 'delslice', 'neg_ovf', 'abs_ovf', 'hint', 'unicode', 'unichr']) for opname in UNARY_OPERATIONS: @@ -274,6 +275,12 @@ s_item.hash() # record that we need the hash of each item return SomeInteger() + def getslice(tup, s_start, s_stop): + assert s_start.is_immutable_constant(),"tuple slicing: needs constants" + assert s_stop.is_immutable_constant(), "tuple slicing: needs constants" + items = tup.items[s_start.const:s_stop.const] + return SomeTuple(items) + class __extend__(SomeList): @@ -283,11 +290,9 @@ def method_extend(lst, s_iterable): lst.listdef.resize() - if isinstance(s_iterable, SomeList): # unify the two lists - lst.listdef.agree(s_iterable.listdef) - else: - s_iter = s_iterable.iter() - lst.method_append(s_iter.next()) + if not isinstance(s_iterable, SomeList): + raise Exception("list.extend(x): x must be a list") + lst.listdef.agree(s_iterable.listdef) def method_reverse(lst): lst.listdef.mutate() @@ -338,6 +343,28 @@ lst = lst.listdef.offspring() return lst + def getslice(lst, s_start, s_stop): + check_negative_slice(s_start, s_stop) + return lst.listdef.offspring() + + def setslice(lst, s_start, s_stop, s_iterable): + check_negative_slice(s_start, s_stop) + if not isinstance(s_iterable, SomeList): + raise Exception("list[start:stop] = x: x must be a list") + lst.listdef.agree(s_iterable.listdef) + # note that setslice is not allowed to resize a list in RPython + + def delslice(lst, s_start, s_stop): + check_negative_slice(s_start, s_stop) + lst.listdef.resize() + +def check_negative_slice(s_start, s_stop): + if isinstance(s_start, SomeInteger) and not s_start.nonneg: + raise TypeError("slicing: not proven to have non-negative start") + if isinstance(s_stop, SomeInteger) and not s_stop.nonneg and \ + getattr(s_stop, 'const', 0) != -1: + raise TypeError("slicing: not proven to have non-negative stop") + class __extend__(SomeDict): @@ -463,6 +490,10 @@ def method_replace(str, s1, s2): return str.basestringclass() + def getslice(str, s_start, s_stop): + check_negative_slice(s_start, s_stop) + return str.basestringclass() + class __extend__(SomeUnicodeString): def method_encode(uni, s_enc): if not s_enc.is_constant(): Modified: pypy/branch/getslice/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/getslice/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/getslice/pypy/interpreter/baseobjspace.py Fri Oct 10 19:38:43 2008 @@ -588,17 +588,6 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - # support for the deprecated __getslice__, __setslice__, __delslice__ - def getslice(self, w_obj, w_start, w_stop): - w_slice = self.newslice(w_start, w_stop, self.w_None) - return self.getitem(w_obj, w_slice) - def setslice(self, w_obj, w_start, w_stop, w_sequence): - w_slice = self.newslice(w_start, w_stop, self.w_None) - self.setitem(w_obj, w_slice, w_sequence) - def delslice(self, w_obj, w_start, w_stop): - w_slice = self.newslice(w_start, w_stop, self.w_None) - self.delitem(w_obj, w_slice) - def interpclass_w(space, w_obj): """ If w_obj is a wrapped internal interpreter class instance unwrap to it, @@ -1032,6 +1021,9 @@ ('getitem', 'getitem', 2, ['__getitem__']), ('setitem', 'setitem', 3, ['__setitem__']), ('delitem', 'delitem', 2, ['__delitem__']), + ('getslice', 'getslice', 3, ['__getslice__']), + ('setslice', 'setslice', 4, ['__setslice__']), + ('delslice', 'delslice', 3, ['__delslice__']), ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__nonzero__']), Modified: pypy/branch/getslice/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/descroperation.py (original) +++ pypy/branch/getslice/pypy/objspace/descroperation.py Fri Oct 10 19:38:43 2008 @@ -228,6 +228,30 @@ space.wrap("cannot delete items from object")) return space.get_and_call_function(w_descr, w_obj, w_key) + def getslice(space, w_obj, w_start, w_stop): + w_descr = space.lookup(w_obj, '__getslice__') + if w_descr is None: + w_slice = space.newslice(w_start, w_stop, space.w_None) + return space.getitem(w_obj, w_slice) + w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) + return space.get_and_call_function(w_descr, w_obj, w_start, w_stop) + + def setslice(space, w_obj, w_start, w_stop, w_sequence): + w_descr = space.lookup(w_obj, '__setslice__') + if w_descr is None: + w_slice = space.newslice(w_start, w_stop, space.w_None) + return space.setitem(w_obj, w_slice, w_sequence) + w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) + return space.get_and_call_function(w_descr, w_obj, w_start, w_stop, w_sequence) + + def delslice(space, w_obj, w_start, w_stop): + w_descr = space.lookup(w_obj, '__delslice__') + if w_descr is None: + w_slice = space.newslice(w_start, w_stop, space.w_None) + return space.delitem(w_obj, w_slice) + w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) + return space.get_and_call_function(w_descr, w_obj, w_start, w_stop) + def pow(space, w_obj1, w_obj2, w_obj3): w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) @@ -453,6 +477,35 @@ return (space.lookup(w_obj, '__int__') is not None or space.lookup(w_obj, '__float__') is not None) + + +# what is the maximum value slices can get on CPython? +# we need to stick to that value, because fake.py etc. +class Temp: + def __getslice__(self, i, j): + return j +slice_max = Temp()[:] +del Temp + +def old_slice_range(space, w_obj, w_start, w_stop): + """Only for backward compatibility for __getslice__()&co methods.""" + if space.is_w(w_start, space.w_None): + w_start = space.wrap(0) + else: + w_start = space.wrap(space.getindex_w(w_start, None)) + if space.is_true(space.lt(w_start, space.wrap(0))): + w_start = space.add(w_start, space.len(w_obj)) + # NB. the language ref is inconsistent with the new-style class + # behavior when w_obj doesn't implement __len__(), so we just + # ignore this case. + if space.is_w(w_stop, space.w_None): + w_stop = space.wrap(slice_max) + else: + w_stop = space.wrap(space.getindex_w(w_stop, None)) + if space.is_true(space.lt(w_stop, space.wrap(0))): + w_stop = space.add(w_stop, space.len(w_obj)) + return w_start, w_stop + # regular methods def helpers def _make_binop_impl(symbol, specialnames): @@ -649,5 +702,3 @@ 'ord', 'unichr', 'unicode']: raise Exception, "missing def for operation %s" % _name - - Modified: pypy/branch/getslice/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/flow/objspace.py (original) +++ pypy/branch/getslice/pypy/objspace/flow/objspace.py Fri Oct 10 19:38:43 2008 @@ -103,7 +103,7 @@ return Constant(slice(self.unwrap(w_start), self.unwrap(w_stop), self.unwrap(w_step))) - return self.do_operation('newslice', w_start, w_stop, w_step) + raise Exception("not supported in RPython: extended slicing") def wrap(self, obj): if isinstance(obj, (Variable, Constant)): Modified: pypy/branch/getslice/pypy/objspace/reflective.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/reflective.py (original) +++ pypy/branch/getslice/pypy/objspace/reflective.py Fri Oct 10 19:38:43 2008 @@ -89,6 +89,14 @@ return parentfn(w_arg1, w_arg2, w_arg3) finally: reset_reflective_space(space, w_old_reflectivespace) + elif args == 4: + def func(self, space, w_arg1, w_arg2, w_arg3, w_arg4): + w_old_reflectivespace = get_reflective_space(space) + set_reflectivespace(space, self.w_reflectivespace) + try: + return parentfn(w_arg1, w_arg2, w_arg3, w_arg4) + finally: + reset_reflective_space(space, w_old_reflectivespace) else: raise NotImplementedError unwrap_spec = ["self", ObjSpace] + [W_Root] * args Modified: pypy/branch/getslice/pypy/objspace/std/builtinshortcut.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/builtinshortcut.py (original) +++ pypy/branch/getslice/pypy/objspace/std/builtinshortcut.py Fri Oct 10 19:38:43 2008 @@ -32,10 +32,16 @@ KNOWN_MISSING = ['getattr', # mostly non-builtins or optimized by CALL_METHOD 'setattr', 'delattr', 'userdel', # mostly for non-builtins 'get', 'set', 'delete', # uncommon (except on functions) - 'delitem', 'abs', 'hex', 'oct', # rare stuff? + 'getslice', 'setslice', 'delslice', # see below + 'delitem', # rare stuff? + 'abs', 'hex', 'oct', # rare stuff? 'pos', 'divmod', 'cmp', # rare stuff? 'float', 'long', 'coerce', # rare stuff? ] +# We cannot support {get,set,del}slice right now because +# DescrOperation.{get,set,del}slice do a bit more work than just call +# the special methods: they call old_slice_range(). See e.g. +# test_builtinshortcut.AppTestString. for _name, _, _, _specialmethods in ObjSpace.MethodTable: if _specialmethods: Modified: pypy/branch/getslice/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/listobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/listobject.py Fri Oct 10 19:38:43 2008 @@ -1,7 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.listtype import get_list_index -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.interpreter import gateway, baseobjspace @@ -80,6 +80,21 @@ start += step return w_res +def getslice__List_ANY_ANY(space, w_list, w_start, w_stop): + length = len(w_list.wrappeditems) + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + return W_ListObject(w_list.wrappeditems[start:stop]) + +def setslice__List_ANY_ANY_ANY(space, w_list, w_start, w_stop, w_sequence): + length = len(w_list.wrappeditems) + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + _setitem_slice_helper(space, w_list, start, 1, stop-start, w_sequence) + +def delslice__List_ANY_ANY(space, w_list, w_start, w_stop): + length = len(w_list.wrappeditems) + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + _delitem_slice_helper(space, w_list, start, 1, stop-start) + def contains__List_ANY(space, w_list, w_obj): # needs to be safe against eq_w() mutating the w_list behind our back i = 0 @@ -190,38 +205,35 @@ space.wrap("list deletion index out of range")) return space.w_None + def delitem__List_Slice(space, w_list, w_slice): start, stop, step, slicelength = w_slice.indices4(space, len(w_list.wrappeditems)) + _delitem_slice_helper(space, w_list, start, step, slicelength) +def _delitem_slice_helper(space, w_list, start, step, slicelength): if slicelength==0: return if step < 0: start = start + step * (slicelength-1) step = -step - # stop is invalid if step == 1: - _del_slice(w_list, start, start+slicelength) + assert start >= 0 + assert slicelength >= 0 + del w_list.wrappeditems[start:start+slicelength] else: items = w_list.wrappeditems n = len(items) - - recycle = [None] * slicelength i = start - # keep a reference to the objects to be removed, - # preventing side effects during destruction - recycle[0] = items[i] - for discard in range(1, slicelength): j = i+1 i += step while j < i: items[j-discard] = items[j] j += 1 - recycle[discard] = items[i] j = i+1 while j < n: @@ -229,13 +241,7 @@ j += 1 start = n - slicelength assert start >= 0 # annotator hint - # XXX allow negative indices in rlist del items[start:] - # now we can destruct recycle safely, regardless of - # side-effects to the list - del recycle[:] - - return space.w_None def setitem__List_ANY_ANY(space, w_list, w_index, w_any): idx = get_list_index(space, w_index) @@ -246,23 +252,25 @@ space.wrap("list index out of range")) return space.w_None -def setitem__List_Slice_List(space, w_list, w_slice, w_list2): - l = w_list2.wrappeditems - return _setitem_slice_helper(space, w_list, w_slice, l, len(l)) - def setitem__List_Slice_ANY(space, w_list, w_slice, w_iterable): - l = space.unpackiterable(w_iterable) - return _setitem_slice_helper(space, w_list, w_slice, l, len(l)) - -def _setitem_slice_helper(space, w_list, w_slice, sequence2, len2): oldsize = len(w_list.wrappeditems) start, stop, step, slicelength = w_slice.indices4(space, oldsize) + _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable) + +def _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable): + if isinstance(w_iterable, W_ListObject): + sequence2 = w_iterable.wrappeditems + else: + sequence2 = space.unpackiterable(w_iterable) + assert slicelength >= 0 items = w_list.wrappeditems - + oldsize = len(items) + len2 = len(sequence2) if step == 1: # Support list resizing for non-extended slices - delta = len2 - slicelength - if delta >= 0: + delta = slicelength - len2 + if delta < 0: + delta = -delta newsize = oldsize + delta # XXX support this in rlist! items += [None] * delta @@ -271,9 +279,10 @@ while i >= lim: items[i] = items[i-delta] i -= 1 + elif start >= 0: + del items[start:start+delta] else: - # shrinking requires the careful memory management of _del_slice() - _del_slice(w_list, start, start-delta) + assert delta==0 elif len2 != slicelength: # No resize for extended slices raise OperationError(space.w_ValueError, space.wrap("attempt to " "assign sequence of size %d to extended slice of size %d" % @@ -290,14 +299,13 @@ items[start] = sequence2[i] start -= step i -= 1 - return space.w_None + return else: # Make a shallow copy to more easily handle the reversal case sequence2 = list(sequence2) for i in range(len2): items[start] = sequence2[i] start += step - return space.w_None app = gateway.applevel(""" def listrepr(currently_in_repr, l): @@ -350,26 +358,6 @@ w_list.wrappeditems += space.unpackiterable(w_any) return space.w_None -def _del_slice(w_list, ilow, ihigh): - """ similar to the deletion part of list_ass_slice in CPython """ - items = w_list.wrappeditems - n = len(items) - if ilow < 0: - ilow = 0 - elif ilow > n: - ilow = n - if ihigh < ilow: - ihigh = ilow - elif ihigh > n: - ihigh = n - # keep a reference to the objects to be removed, - # preventing side effects during destruction - recycle = items[ilow:ihigh] - del items[ilow:ihigh] - # now we can destruct recycle safely, regardless of - # side-effects to the list - del recycle[:] - # note that the default value will come back wrapped!!! def list_pop__List_ANY(space, w_list, w_idx=-1): items = w_list.wrappeditems Modified: pypy/branch/getslice/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/objspace.py (original) +++ pypy/branch/getslice/pypy/objspace/std/objspace.py Fri Oct 10 19:38:43 2008 @@ -764,33 +764,6 @@ else: return ObjSpace.call_method(self, w_obj, methname, *arg_w) - # support for the deprecated __getslice__, __setslice__, __delslice__ - - def getslice(self, w_obj, w_start, w_stop): - w_descr = self.lookup(w_obj, '__getslice__') - if w_descr is not None: - w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) - return self.get_and_call_function(w_descr, w_obj, w_start, w_stop) - else: - return ObjSpace.getslice(self, w_obj, w_start, w_stop) - - def setslice(self, w_obj, w_start, w_stop, w_sequence): - w_descr = self.lookup(w_obj, '__setslice__') - if w_descr is not None: - w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) - self.get_and_call_function(w_descr, w_obj, w_start, w_stop, - w_sequence) - else: - ObjSpace.setslice(self, w_obj, w_start, w_stop, w_sequence) - - def delslice(self, w_obj, w_start, w_stop): - w_descr = self.lookup(w_obj, '__delslice__') - if w_descr is not None: - w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) - self.get_and_call_function(w_descr, w_obj, w_start, w_stop) - else: - ObjSpace.delslice(self, w_obj, w_start, w_stop) - def raise_key_error(self, w_key): e = self.call_function(self.w_KeyError, w_key) raise OperationError(self.w_KeyError, e) @@ -820,32 +793,3 @@ del mm pow.extras['defaults'] = (None,) - - -# what is the maximum value slices can get on CPython? -# we need to stick to that value, because fake.py etc. -class Temp: - def __getslice__(self, i, j): - return j -slice_max = Temp()[:] -del Temp - - -def old_slice_range(space, w_obj, w_start, w_stop): - """Only for backward compatibility for __getslice__()&co methods.""" - if space.is_w(w_start, space.w_None): - w_start = space.wrap(0) - else: - w_start = space.wrap(space.getindex_w(w_start, None)) - if space.is_true(space.lt(w_start, space.wrap(0))): - w_start = space.add(w_start, space.len(w_obj)) - # NB. the language ref is inconsistent with the new-style class - # behavior when w_obj doesn't implement __len__(), so we just - # ignore this case. - if space.is_w(w_stop, space.w_None): - w_stop = space.wrap(slice_max) - else: - w_stop = space.wrap(space.getindex_w(w_stop, None)) - if space.is_true(space.lt(w_stop, space.wrap(0))): - w_stop = space.add(w_stop, space.len(w_obj)) - return w_start, w_stop Modified: pypy/branch/getslice/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/rangeobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/rangeobject.py Fri Oct 10 19:38:43 2008 @@ -1,7 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std import listtype from pypy.objspace.std import iterobject @@ -100,6 +100,17 @@ rangestep = w_rangelist.step * step return W_RangeListObject(rangestart, rangestep, slicelength) +def getslice__RangeList_ANY_ANY(space, w_rangelist, w_start, w_stop): + if w_rangelist.w_list is not None: + return space.getslice(w_rangelist.w_list, w_start, w_stop) + length = w_rangelist.length + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + slicelength = stop - start + assert slicelength >= 0 + rangestart = w_rangelist.getitem_unchecked(start) + rangestep = w_rangelist.step + return W_RangeListObject(rangestart, rangestep, slicelength) + def iter__RangeList(space, w_rangelist): return W_RangeIterObject(w_rangelist) Modified: pypy/branch/getslice/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/ropeobject.py Fri Oct 10 19:38:43 2008 @@ -2,7 +2,7 @@ from pypy.interpreter import gateway from pypy.rlib.objectmodel import we_are_translated from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.noneobject import W_NoneObject @@ -693,6 +693,15 @@ return W_RopeObject.EMPTY return W_RopeObject(rope.getslice(node, start, stop, step, sl)) +def getslice__Rope_ANY_ANY(space, w_str, w_start, w_stop): + node = w_str._node + length = node.length() + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + sl = stop - start + if sl == 0: + return W_RopeObject.EMPTY + return W_RopeObject(rope.getslice(node, start, stop, 1, sl)) + def mul_string_times(space, w_str, w_times): try: mul = space.getindex_w(w_times, space.w_OverflowError) Modified: pypy/branch/getslice/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/ropeunicodeobject.py Fri Oct 10 19:38:43 2008 @@ -5,7 +5,7 @@ from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib import rope -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.objspace.std.tupleobject import W_TupleObject from pypy.rlib.rarithmetic import intmask, ovfcheck @@ -287,6 +287,15 @@ return W_RopeUnicodeObject.EMPTY return W_RopeUnicodeObject(rope.getslice(node, start, stop, step, sl)) +def getslice__RopeUnicode_ANY_ANY(space, w_uni, w_start, w_stop): + node = w_uni._node + length = node.length() + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + sl = stop - start + if sl == 0: + return W_RopeUnicodeObject.EMPTY + return W_RopeUnicodeObject(rope.getslice(node, start, stop, 1, sl)) + def mul__RopeUnicode_ANY(space, w_uni, w_times): try: times = space.getindex_w(w_times, space.w_OverflowError) Modified: pypy/branch/getslice/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/sliceobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/sliceobject.py Fri Oct 10 19:38:43 2008 @@ -79,6 +79,19 @@ registerimplementation(W_SliceObject) +def normalize_simple_slice(space, length, w_start, w_stop): + """Helper for the {get,set,del}slice multimethod implementations.""" + start = space.int_w(w_start) + stop = space.int_w(w_stop) + if start < 0: + start = 0 + if stop > length: + stop = length + if stop < start: + stop = start + return start, stop + + repr__Slice = gateway.applevel(""" def repr__Slice(aslice): return 'slice(%r, %r, %r)' % (aslice.start, aslice.stop, aslice.step) Modified: pypy/branch/getslice/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/stringobject.py Fri Oct 10 19:38:43 2008 @@ -5,7 +5,7 @@ from pypy.rlib.rarithmetic import ovfcheck, _hash_string from pypy.rlib.objectmodel import we_are_translated from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.noneobject import W_NoneObject @@ -803,6 +803,14 @@ str = "".join([s[start + i*step] for i in range(sl)]) return wrapstr(space, str) +def getslice__String_ANY_ANY(space, w_str, w_start, w_stop): + s = w_str._value + start, stop = normalize_simple_slice(space, len(s), w_start, w_stop) + if start == stop: + return W_StringObject.EMPTY + else: + return sliced(space, s, start, stop) + def mul_string_times(space, w_str, w_times): try: mul = space.getindex_w(w_times, space.w_OverflowError) Modified: pypy/branch/getslice/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/strsliceobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/strsliceobject.py Fri Oct 10 19:38:43 2008 @@ -1,7 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std import slicetype from pypy.objspace.std.inttype import wrapint @@ -194,6 +194,18 @@ str = "".join([s[start + i*step] for i in range(sl)]) return wrapstr(space, str) +def getslice__StringSlice_ANY_ANY(space, w_str, w_start, w_stop): + length = w_str.stop - w_str.start + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + sl = stop - start + if sl == 0: + return W_StringObject.EMPTY + else: + s = w_str.str + start = w_str.start + start + stop = w_str.start + stop + return W_StringSliceObject(s, start, stop) + def len__StringSlice(space, w_str): return space.wrap(w_str.stop - w_str.start) Modified: pypy/branch/getslice/pypy/objspace/std/test/test_builtinshortcut.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/test/test_builtinshortcut.py (original) +++ pypy/branch/getslice/pypy/objspace/std/test/test_builtinshortcut.py Fri Oct 10 19:38:43 2008 @@ -1,5 +1,6 @@ from pypy.objspace.std.test import test_userobject from pypy.objspace.std.test import test_set +from pypy.objspace.std.test import test_stringobject WITH_BUILTINSHORTCUT = {'objspace.std.builtinshortcut': True} @@ -38,3 +39,8 @@ def setup_class(cls): from pypy import conftest cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) + +class AppTestString(test_stringobject.AppTestStringObject): + def setup_class(cls): + from pypy import conftest + cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) Modified: pypy/branch/getslice/pypy/objspace/std/test/test_listmultiobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/test/test_listmultiobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/test/test_listmultiobject.py Fri Oct 10 19:38:43 2008 @@ -39,6 +39,15 @@ # These few here ^ would have failed before, but for good coverage, # all the list methods etc. should be tested also... + def test___getslice__(self): + skip("don't care for now") + + def test___setslice__(self): + skip("don't care for now") + + def test___delslice__(self): + skip("don't care for now") + class AppTest_ListMultiObject(BaseAppTest_ListMultiObject): def setup_class(cls): BaseAppTest_ListMultiObject.setup_class(cls) Modified: pypy/branch/getslice/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/test/test_listobject.py Fri Oct 10 19:38:43 2008 @@ -754,3 +754,18 @@ A() while lst: keepalive.append(lst[:]) + + def test___getslice__(self): + l = [1,2,3,4] + res = l.__getslice__(0, 2) + assert res == [1, 2] + + def test___setslice__(self): + l = [1,2,3,4] + l.__setslice__(0, 2, [5, 6]) + assert l == [5, 6, 3, 4] + + def test___delslice__(self): + l = [1,2,3,4] + l.__delslice__(0, 2) + assert l == [3, 4] Modified: pypy/branch/getslice/pypy/objspace/std/test/test_rangeobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/test/test_rangeobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/test/test_rangeobject.py Fri Oct 10 19:38:43 2008 @@ -29,6 +29,14 @@ def test_getitem_slice(self): result = [] r = range(1, 100, 2) + for i in r[10:15]: + result.append(i) + assert result == [21, 23, 25, 27, 29] + assert self.not_forced(r) + + def test_getitem_extended_slice(self): + result = [] + r = range(1, 100, 2) for i in r[40:30:-2]: result.append(i) assert result == [81, 77, 73, 69, 65] Modified: pypy/branch/getslice/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/test/test_stringobject.py Fri Oct 10 19:38:43 2008 @@ -714,6 +714,20 @@ assert x.rstrip(y) == '' assert x.lstrip(y) == '' + def test_getslice(self): + assert "foobar".__getslice__(4, 4321) == "ar" + s = "abc" + assert s[:] == "abc" + assert s[1:] == "bc" + assert s[:2] == "ab" + assert s[1:2] == "b" + assert s[-2:] == "bc" + assert s[:-1] == "ab" + assert s[-2:2] == "b" + assert s[1:-1] == "b" + assert s[-2:-1] == "b" + + class AppTestPrebuilt(AppTestStringObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True}) Modified: pypy/branch/getslice/pypy/objspace/std/test/test_strsliceobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/test/test_strsliceobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/test/test_strsliceobject.py Fri Oct 10 19:38:43 2008 @@ -133,3 +133,16 @@ assert s.count("X") == 100 assert s.count("Y") == 100 assert self.not_forced(s) + + def test_extended_slice(self): + import __pypy__ + def slice1(s): return (s*3)[len(s):-len(s)] + s = slice1('0123456789' * 20) + assert len(s) == 200 + assert self.not_forced(s) + t = s[::-1] + assert t == '9876543210' * 20 + assert not self.not_forced(t) + u = s[slice(10, 20)] + assert self.not_forced(u) + assert u == '0123456789' Modified: pypy/branch/getslice/pypy/objspace/std/test/test_tupleobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/test/test_tupleobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/test/test_tupleobject.py Fri Oct 10 19:38:43 2008 @@ -318,3 +318,5 @@ assert repr(()) == '()' assert repr((1,2,3)) == '(1, 2, 3)' + def test_getslice(self): + assert ('a', 'b', 'c').__getslice__(-17, 2) == ('a', 'b') Modified: pypy/branch/getslice/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/test/test_unicodeobject.py Fri Oct 10 19:38:43 2008 @@ -641,3 +641,15 @@ assert unicode(Y()).__class__ is X + def test_getslice(self): + assert u'123456'.__getslice__(1, 5) == u'2345' + s = u"abc" + assert s[:] == "abc" + assert s[1:] == "bc" + assert s[:2] == "ab" + assert s[1:2] == "b" + assert s[-2:] == "bc" + assert s[:-1] == "ab" + assert s[-2:2] == "b" + assert s[1:-1] == "b" + assert s[-2:-1] == "b" Modified: pypy/branch/getslice/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/tupleobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/tupleobject.py Fri Oct 10 19:38:43 2008 @@ -1,7 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.inttype import wrapint from pypy.rlib.rarithmetic import intmask -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.interpreter import gateway from pypy.rlib.debug import make_sure_not_resized @@ -53,6 +53,11 @@ start += step return W_TupleObject(subitems) +def getslice__Tuple_ANY_ANY(space, w_tuple, w_start, w_stop): + length = len(w_tuple.wrappeditems) + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + return W_TupleObject(w_tuple.wrappeditems[start:stop]) + def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): Modified: pypy/branch/getslice/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/getslice/pypy/objspace/std/unicodeobject.py Fri Oct 10 19:38:43 2008 @@ -3,7 +3,7 @@ from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.objspace.std.tupleobject import W_TupleObject from pypy.rlib.rarithmetic import intmask, ovfcheck @@ -247,6 +247,11 @@ r = u"".join([uni[start + i*step] for i in range(sl)]) return W_UnicodeObject(r) +def getslice__Unicode_ANY_ANY(space, w_uni, w_start, w_stop): + uni = w_uni._value + start, stop = normalize_simple_slice(space, len(uni), w_start, w_stop) + return W_UnicodeObject(uni[start:stop]) + def mul__Unicode_ANY(space, w_uni, w_times): try: times = space.getindex_w(w_times, space.w_OverflowError) Modified: pypy/branch/getslice/pypy/objspace/thunk.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/thunk.py (original) +++ pypy/branch/getslice/pypy/objspace/thunk.py Fri Oct 10 19:38:43 2008 @@ -193,6 +193,13 @@ w2 = force(space, w2) w3 = force(space, w3) return parentfn(w1, w2, w3, *extra) + elif nb_args == 4: + def proxy(w1, w2, w3, w4, *extra): + w1 = force(space, w1) + w2 = force(space, w2) + w3 = force(space, w3) + w4 = force(space, w4) + return parentfn(w1, w2, w3, w4, *extra) else: raise NotImplementedError("operation %r has arity %d" % (opname, nb_args)) Modified: pypy/branch/getslice/pypy/rpython/lltypesystem/rlist.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/lltypesystem/rlist.py (original) +++ pypy/branch/getslice/pypy/rpython/lltypesystem/rlist.py Fri Oct 10 19:38:43 2008 @@ -7,9 +7,6 @@ AbstractFixedSizeListRepr, AbstractListIteratorRepr, rtype_newlist, \ rtype_alloc_and_set, ll_setitem_nonneg, ADTIList, ADTIFixedList from pypy.rpython.rlist import dum_nocheck, dum_checkidx -from pypy.rpython.lltypesystem.rslice import SliceRepr -from pypy.rpython.lltypesystem.rslice import startstop_slice_repr, startonly_slice_repr -from pypy.rpython.lltypesystem.rslice import minusone_slice_repr from pypy.rpython.lltypesystem.lltype import \ GcForwardReference, Ptr, GcArray, GcStruct, \ Void, Signed, malloc, typeOf, Primitive, \ Modified: pypy/branch/getslice/pypy/rpython/ootypesystem/rlist.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/ootypesystem/rlist.py (original) +++ pypy/branch/getslice/pypy/rpython/ootypesystem/rlist.py Fri Oct 10 19:38:43 2008 @@ -5,8 +5,6 @@ from pypy.rpython.rmodel import inputconst, externalvsinternal from pypy.rpython.lltypesystem.lltype import Signed, Void from pypy.rpython.ootypesystem import ootype -from pypy.rpython.ootypesystem.rslice import SliceRepr, \ - startstop_slice_repr, startonly_slice_repr, minusone_slice_repr from pypy.rpython.ootypesystem import rstr Modified: pypy/branch/getslice/pypy/rpython/rlist.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/rlist.py (original) +++ pypy/branch/getslice/pypy/rpython/rlist.py Fri Oct 10 19:38:43 2008 @@ -3,7 +3,6 @@ from pypy.annotation import model as annmodel from pypy.rpython.error import TyperError from pypy.rpython.rmodel import Repr, IteratorRepr, IntegerRepr, inputconst -from pypy.rpython.rslice import AbstractSliceRepr 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 @@ -403,47 +402,30 @@ return v_lst1 -class __extend__(pairtype(AbstractBaseListRepr, AbstractSliceRepr)): +class __extend__(AbstractBaseListRepr): - def rtype_getitem((r_lst, r_slic), hop): - rs = r_lst.rtyper.type_system.rslice + def rtype_getslice(r_lst, hop): cRESLIST = hop.inputconst(Void, hop.r_result.LIST) - if r_slic == rs.startonly_slice_repr: - v_lst, v_start = hop.inputargs(r_lst, rs.startonly_slice_repr) - return hop.gendirectcall(ll_listslice_startonly, cRESLIST, v_lst, v_start) - if r_slic == rs.startstop_slice_repr: - v_lst, v_slice = hop.inputargs(r_lst, rs.startstop_slice_repr) - return hop.gendirectcall(ll_listslice, cRESLIST, v_lst, v_slice) - if r_slic == rs.minusone_slice_repr: - v_lst, v_ignored = hop.inputargs(r_lst, rs.minusone_slice_repr) - return hop.gendirectcall(ll_listslice_minusone, cRESLIST, v_lst) - raise TyperError('getitem does not support slices with %r' % (r_slic,)) - - def rtype_setitem((r_lst, r_slic), hop): - #if r_slic == startonly_slice_repr: - # not implemented - rs = r_lst.rtyper.type_system.rslice - if r_slic == rs.startstop_slice_repr: - v_lst, v_slice, v_lst2 = hop.inputargs(r_lst, rs.startstop_slice_repr, - hop.args_r[2]) - hop.gendirectcall(ll_listsetslice, v_lst, v_slice, v_lst2) - return - raise TyperError('setitem does not support slices with %r' % (r_slic,)) - - -class __extend__(pairtype(AbstractListRepr, AbstractSliceRepr)): - - def rtype_delitem((r_lst, r_slic), hop): - rs = r_lst.rtyper.type_system.rslice - if r_slic == rs.startonly_slice_repr: - v_lst, v_start = hop.inputargs(r_lst, rs.startonly_slice_repr) - hop.gendirectcall(ll_listdelslice_startonly, v_lst, v_start) - return - if r_slic == rs.startstop_slice_repr: - v_lst, v_slice = hop.inputargs(r_lst, rs.startstop_slice_repr) - hop.gendirectcall(ll_listdelslice, v_lst, v_slice) - return - raise TyperError('delitem does not support slices with %r' % (r_slic,)) + v_lst = hop.inputarg(r_lst, arg=0) + kind, vlist = hop.decompose_slice_args() + ll_listslice = globals()['ll_listslice_%s' % kind] + return hop.gendirectcall(ll_listslice, cRESLIST, v_lst, *vlist) + + def rtype_setslice(r_lst, hop): + v_lst = hop.inputarg(r_lst, arg=0) + kind, vlist = hop.decompose_slice_args() + if kind != 'startstop': + raise TyperError('list.setitem does not support %r slices' % ( + kind,)) + v_start, v_stop = vlist + v_lst2 = hop.inputarg(hop.args_r[3], arg=3) + hop.gendirectcall(ll_listsetslice, v_lst, v_start, v_stop, v_lst2) + + def rtype_delslice(r_lst, hop): + v_lst = hop.inputarg(r_lst, arg=0) + kind, vlist = hop.decompose_slice_args() + ll_listdelslice = globals()['ll_listdelslice_%s' % kind] + return hop.gendirectcall(ll_listdelslice, v_lst, *vlist) # ____________________________________________________________ @@ -868,9 +850,7 @@ j += 1 return l -def ll_listslice(RESLIST, l1, slice): - start = slice.start - stop = slice.stop +def ll_listslice_startstop(RESLIST, l1, start, stop): length = l1.ll_length() ll_assert(start >= 0, "unexpectedly negative list slice start") ll_assert(start <= length, "list slice start larger than list length") @@ -909,9 +889,7 @@ j -= 1 l._ll_resize_le(newlength) -def ll_listdelslice(l, slice): - start = slice.start - stop = slice.stop +def ll_listdelslice_startstop(l, start, stop): length = l.ll_length() ll_assert(start >= 0, "del l[start:x] with unexpectedly negative start") ll_assert(start <= length, "del l[start:x] with start > len(l)") @@ -933,12 +911,11 @@ j -= 1 l._ll_resize_le(newlength) -def ll_listsetslice(l1, slice, l2): +def ll_listsetslice(l1, start, stop, l2): count = l2.ll_length() - start = slice.start ll_assert(start >= 0, "l[start:x] = l with unexpectedly negative start") ll_assert(start <= l1.ll_length(), "l[start:x] = l with start > len(l)") - ll_assert(count == slice.stop - start, + ll_assert(count == stop - start, "setslice cannot resize lists in RPython") # XXX but it should be easy enough to support, soon j = start Modified: pypy/branch/getslice/pypy/rpython/rstr.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/rstr.py (original) +++ pypy/branch/getslice/pypy/rpython/rstr.py Fri Oct 10 19:38:43 2008 @@ -5,7 +5,6 @@ from pypy.rpython.rmodel import IntegerRepr, IteratorRepr from pypy.rpython.rmodel import inputconst, Repr from pypy.rpython.rtuple import AbstractTupleRepr -from pypy.rpython.rslice import AbstractSliceRepr from pypy.rpython import rint from pypy.rpython.lltypesystem.lltype import Signed, Bool, Void, UniChar,\ cast_primitive @@ -331,22 +330,22 @@ rtype_getitem_idx_key = rtype_getitem_idx -class __extend__(pairtype(AbstractStringRepr, AbstractSliceRepr)): +##class __extend__(pairtype(AbstractStringRepr, AbstractSliceRepr)): - def rtype_getitem((r_str, r_slic), hop): - string_repr = r_str.repr - rslice = hop.rtyper.type_system.rslice - - if r_slic == rslice.startonly_slice_repr: - v_str, v_start = hop.inputargs(string_repr, rslice.startonly_slice_repr) - return hop.gendirectcall(r_str.ll.ll_stringslice_startonly, v_str, v_start) - if r_slic == rslice.startstop_slice_repr: - v_str, v_slice = hop.inputargs(string_repr, rslice.startstop_slice_repr) - return hop.gendirectcall(r_str.ll.ll_stringslice, v_str, v_slice) - if r_slic == rslice.minusone_slice_repr: - v_str, v_ignored = hop.inputargs(string_repr, rslice.minusone_slice_repr) - return hop.gendirectcall(r_str.ll.ll_stringslice_minusone, v_str) - raise TyperError(r_slic) +## def rtype_getitem((r_str, r_slic), hop): +## string_repr = r_str.repr +## rslice = hop.rtyper.type_system.rslice + +## if r_slic == rslice.startonly_slice_repr: +## v_str, v_start = hop.inputargs(string_repr, rslice.startonly_slice_repr) +## return hop.gendirectcall(r_str.ll.ll_stringslice_startonly, v_str, v_start) +## if r_slic == rslice.startstop_slice_repr: +## v_str, v_slice = hop.inputargs(string_repr, rslice.startstop_slice_repr) +## return hop.gendirectcall(r_str.ll.ll_stringslice, v_str, v_slice) +## if r_slic == rslice.minusone_slice_repr: +## v_str, v_ignored = hop.inputargs(string_repr, rslice.minusone_slice_repr) +## return hop.gendirectcall(r_str.ll.ll_stringslice_minusone, v_str) +## raise TyperError(r_slic) class __extend__(pairtype(AbstractStringRepr, AbstractStringRepr)): def rtype_add((r_str1, r_str2), hop): Modified: pypy/branch/getslice/pypy/rpython/rtuple.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/rtuple.py (original) +++ pypy/branch/getslice/pypy/rpython/rtuple.py Fri Oct 10 19:38:43 2008 @@ -6,7 +6,6 @@ from pypy.rpython.rmodel import Repr, IntegerRepr, inputconst from pypy.rpython.rmodel import IteratorRepr from pypy.rpython.rmodel import externalvsinternal -from pypy.rpython.rslice import AbstractSliceRepr from pypy.rpython.lltypesystem.lltype import Void, Signed, Bool from pypy.rlib.rarithmetic import intmask from pypy.rlib.unroll import unrolling_iterable @@ -242,18 +241,18 @@ index = v_index.value return r_tup.getitem(hop.llops, v_tuple, index) -class __extend__(pairtype(AbstractTupleRepr, AbstractSliceRepr)): +##class __extend__(pairtype(AbstractTupleRepr, AbstractSliceRepr)): - def rtype_getitem((r_tup, r_slice), hop): - v_tup = hop.inputarg(r_tup, arg=0) - s_slice = hop.args_s[1] - start, stop, step = s_slice.constant_indices() - indices = range(len(r_tup.items_r))[start:stop:step] - assert len(indices) == len(hop.r_result.items_r) - - items_v = [r_tup.getitem_internal(hop.llops, v_tup, i) - for i in indices] - return hop.r_result.newtuple(hop.llops, hop.r_result, items_v) +## def rtype_getitem((r_tup, r_slice), hop): +## v_tup = hop.inputarg(r_tup, arg=0) +## s_slice = hop.args_s[1] +## start, stop, step = s_slice.constant_indices() +## indices = range(len(r_tup.items_r))[start:stop:step] +## assert len(indices) == len(hop.r_result.items_r) + +## items_v = [r_tup.getitem_internal(hop.llops, v_tup, i) +## for i in indices] +## return hop.r_result.newtuple(hop.llops, hop.r_result, items_v) class __extend__(pairtype(AbstractTupleRepr, Repr)): def rtype_contains((r_tup, r_item), hop): Modified: pypy/branch/getslice/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/rtyper.py (original) +++ pypy/branch/getslice/pypy/rpython/rtyper.py Fri Oct 10 19:38:43 2008 @@ -811,6 +811,32 @@ return # ignored for high-level ops before the last one in the block self.llops.llop_raising_exceptions = "removed" + def decompose_slice_args(self): + # Select which kind of slicing is needed. We support: + # * [start:] + # * [start:stop] + # * [:-1] + s_start = self.args_s[1] + s_stop = self.args_s[2] + if (s_start.is_constant() and s_start.const in (None, 0) and + s_stop.is_constant() and s_stop.const == -1): + return "minusone", [] + if isinstance(s_start, annmodel.SomeInteger): + if not s_start.nonneg: + raise TyperError("slice start must be proved non-negative") + if isinstance(s_stop, annmodel.SomeInteger): + if not s_stop.nonneg: + raise TyperError("slice stop must be proved non-negative") + if s_start.is_constant() and s_start.const is None: + v_start = inputconst(Signed, 0) + else: + v_start = self.inputarg(Signed, arg=1) + if s_stop.is_constant() and s_stop.const is None: + return "startonly", [v_start] + else: + v_stop = self.inputarg(Signed, arg=2) + return "startstop", [v_start, v_stop] + # ____________________________________________________________ class LowLevelOpList(list): @@ -935,7 +961,7 @@ # and the rtyper_chooserepr() methods from pypy.rpython import robject from pypy.rpython import rint, rbool, rfloat -from pypy.rpython import rslice, rrange +from pypy.rpython import rrange from pypy.rpython import rstr, rdict, rlist from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase from pypy.rpython import rexternalobj Modified: pypy/branch/getslice/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/test/test_rlist.py (original) +++ pypy/branch/getslice/pypy/rpython/test/test_rlist.py Fri Oct 10 19:38:43 2008 @@ -7,7 +7,6 @@ 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.ootypesystem import rlist as oo_rlist -from pypy.rpython.lltypesystem.rslice import ll_newslice from pypy.rpython.rint import signed_repr from pypy.translator.translator import TranslationContext from pypy.objspace.flow.model import Constant, Variable @@ -58,8 +57,8 @@ self.check_list(ll_listslice_startonly(LIST, l, 4), []) for start in range(5): for stop in range(start, 8): - s = ll_newslice(start, stop) - self.check_list(ll_listslice(LIST, l, s), [42, 43, 44, 45][start:stop]) + self.check_list(ll_listslice_startstop(LIST, l, start, stop), + [42, 43, 44, 45][start:stop]) def test_rlist_setslice(self): n = 100 @@ -72,9 +71,8 @@ expected[i] = n ll_setitem(l2, i, n) n += 1 - s = ll_newslice(start, stop) - l2 = ll_listslice(typeOf(l2).TO, l2, s) - ll_listsetslice(l1, s, l2) + l2 = ll_listslice_startstop(typeOf(l2).TO, l2, start, stop) + ll_listsetslice(l1, start, stop, l2) self.check_list(l1, expected) @@ -129,8 +127,7 @@ for start in range(5): for stop in range(start, 8): l = self.sample_list() - s = ll_newslice(start, stop) - ll_listdelslice(l, s) + ll_listdelslice_startstop(l, start, stop) expected = [42, 43, 44, 45] del expected[start:stop] self.check_list(l, expected) @@ -380,6 +377,25 @@ assert res.item2 == 8 assert res.item3 == 7 + def test_delslice(self): + def dummyfn(): + l = [10, 9, 8, 7] + del l[:2] + return len(l), l[0], l[1] + res = self.interpret(dummyfn, ()) + assert res.item0 == 2 + assert res.item1 == 8 + assert res.item2 == 7 + + def dummyfn(): + l = [10, 9, 8, 7] + del l[2:] + return len(l), l[0], l[1] + res = self.interpret(dummyfn, ()) + assert res.item0 == 2 + assert res.item1 == 10 + assert res.item2 == 9 + def test_bltn_list(self): def dummyfn(): l1 = [42] Modified: pypy/branch/getslice/pypy/translator/simplify.py ============================================================================== --- pypy/branch/getslice/pypy/translator/simplify.py (original) +++ pypy/branch/getslice/pypy/translator/simplify.py Fri Oct 10 19:38:43 2008 @@ -483,7 +483,7 @@ # (they have no side effects, at least in R-Python) CanRemove = {} for _op in ''' - newtuple newlist newdict newslice is_true + newtuple newlist newdict is_true is_ id type issubtype repr str len hash getattr getitem pos neg nonzero abs hex oct ord invert add sub mul truediv floordiv div mod divmod pow lshift rshift and_ or_ Modified: pypy/branch/getslice/pypy/translator/transform.py ============================================================================== --- pypy/branch/getslice/pypy/translator/transform.py (original) +++ pypy/branch/getslice/pypy/translator/transform.py Fri Oct 10 19:38:43 2008 @@ -112,30 +112,6 @@ op.result) block.operations[i] = new_op -# a[b:c] -# --> -# d = newslice(b, c, None) -# e = getitem(a, d) -# --> -# e = getslice(a, b, c) - -##def transform_slice(self, block_subset): -- not used any more -- -## """Transforms a[b:c] to getslice(a, b, c).""" -## for block in block_subset: -## operations = block.operations[:] -## n_op = len(operations) -## for i in range(0, n_op-1): -## op1 = operations[i] -## op2 = operations[i+1] -## if (op1.opname == 'newslice' and -## self.gettype(op1.args[2]) is types.NoneType and -## op2.opname == 'getitem' and -## op1.result is op2.args[1]): -## new_op = SpaceOperation('getslice', -## (op2.args[0], op1.args[0], op1.args[1]), -## op2.result) -## block.operations[i+1:i+2] = [new_op] - def transform_dead_op_vars(self, block_subset): # we redo the same simplification from simplify.py, From iko at codespeak.net Fri Oct 10 19:51:19 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 10 Oct 2008 19:51:19 +0200 (CEST) Subject: [pypy-svn] r58931 - pypy/branch/2.5-merge/pypy/objspace/std Message-ID: <20081010175119.95E2B16A1AC@codespeak.net> Author: iko Date: Fri Oct 10 19:51:19 2008 New Revision: 58931 Modified: pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py Log: Fix incorrect variable name Modified: pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py Fri Oct 10 19:51:19 2008 @@ -263,13 +263,14 @@ def _split_helper(space, value, sep, maxsplit): res_w = [] start = 0 + seplen = len(sep) while maxsplit != 0: - next = value.find(by, start) + next = value.find(sep, start) if next < 0: break res_w.append(sliced(space, value, start, next)) - start = next + bylen + start = next + seplen maxsplit -= 1 # NB. if it's already < 0, it stays < 0 res_w.append(sliced(space, value, start, len(value))) From iko at codespeak.net Fri Oct 10 20:02:55 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 10 Oct 2008 20:02:55 +0200 (CEST) Subject: [pypy-svn] r58933 - pypy/branch/2.5-merge/pypy/objspace/std Message-ID: <20081010180255.325CA16A129@codespeak.net> Author: iko Date: Fri Oct 10 20:02:54 2008 New Revision: 58933 Modified: pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py Log: (iko, cfbolz) _split_helper didn't work out, revert a bit Modified: pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/stringobject.py Fri Oct 10 20:02:54 2008 @@ -260,30 +260,25 @@ return space.newlist(res_w) -def _split_helper(space, value, sep, maxsplit): +def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): + maxsplit = space.int_w(w_maxsplit) + value = w_self._value + by = w_by._value + bylen = len(by) + if bylen == 0: + raise OperationError(space.w_ValueError, space.wrap("empty separator")) + res_w = [] start = 0 - seplen = len(sep) - while maxsplit != 0: - next = value.find(sep, start) + next = value.find(by, start) if next < 0: break res_w.append(sliced(space, value, start, next)) - start = next + seplen + start = next + bylen maxsplit -= 1 # NB. if it's already < 0, it stays < 0 res_w.append(sliced(space, value, start, len(value))) - -def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): - maxsplit = space.int_w(w_maxsplit) - value = w_self._value - by = w_by._value - bylen = len(by) - if bylen == 0: - raise OperationError(space.w_ValueError, space.wrap("empty separator")) - - res_w = _split_helper(space, value, by, maxsplit) return space.newlist(res_w) def str_rsplit__String_None_ANY(space, w_self, w_none, w_maxsplit=-1): @@ -494,8 +489,20 @@ substrings_w.append(c) substrings_w.append(input[upper:]) else: - substrings_w = _split_helper(space, input, sub, maxsplit) - + start = 0 + sublen = len(sub) + substrings_w = [] + + while maxsplit != 0: + next = input.find(sub, start) + if next < 0: + break + substrings_w.append(input[start:next]) + start = next + sublen + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + substrings_w.append(input[start:]) + try: # XXX conservative estimate. If your strings are that close # to overflowing, bad luck. From arigo at codespeak.net Fri Oct 10 20:14:03 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 10 Oct 2008 20:14:03 +0200 (CEST) Subject: [pypy-svn] r58936 - in pypy/branch/getslice/pypy: annotation objspace/flow/test rpython rpython/lltypesystem rpython/ootypesystem translator Message-ID: <20081010181403.A459416A0B1@codespeak.net> Author: arigo Date: Fri Oct 10 20:14:02 2008 New Revision: 58936 Modified: pypy/branch/getslice/pypy/annotation/unaryop.py pypy/branch/getslice/pypy/objspace/flow/test/test_objspace.py pypy/branch/getslice/pypy/rpython/lltypesystem/rstr.py pypy/branch/getslice/pypy/rpython/ootypesystem/rstr.py pypy/branch/getslice/pypy/rpython/rlist.py pypy/branch/getslice/pypy/rpython/rstr.py pypy/branch/getslice/pypy/rpython/rtyper.py pypy/branch/getslice/pypy/translator/transform.py Log: (antocuni, arigo) More in-progress stuff. Modified: pypy/branch/getslice/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/getslice/pypy/annotation/unaryop.py (original) +++ pypy/branch/getslice/pypy/annotation/unaryop.py Fri Oct 10 20:14:02 2008 @@ -290,9 +290,11 @@ def method_extend(lst, s_iterable): lst.listdef.resize() - if not isinstance(s_iterable, SomeList): - raise Exception("list.extend(x): x must be a list") - lst.listdef.agree(s_iterable.listdef) + if isinstance(s_iterable, SomeList): # unify the two lists + lst.listdef.agree(s_iterable.listdef) + else: + s_iter = s_iterable.iter() + lst.method_append(s_iter.next()) def method_reverse(lst): lst.listdef.mutate() Modified: pypy/branch/getslice/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/branch/getslice/pypy/objspace/flow/test/test_objspace.py Fri Oct 10 20:14:02 2008 @@ -851,6 +851,13 @@ return foolist[0] py.test.raises(RuntimeError, "self.codetest(f)") + def test_getslice_constfold(self): + def f(): + s = 'hello' + return s[:3] + graph = self.codetest(f) + assert not self.all_operations(graph) + class TestFlowObjSpaceDelay(Base): def setup_class(cls): cls.space = FlowObjSpace() Modified: pypy/branch/getslice/pypy/rpython/lltypesystem/rstr.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/lltypesystem/rstr.py (original) +++ pypy/branch/getslice/pypy/rpython/lltypesystem/rstr.py Fri Oct 10 20:14:02 2008 @@ -640,9 +640,7 @@ s1.copy_contents(s1, newstr, start, 0, lgt) return newstr - def ll_stringslice(s1, slice): - start = slice.start - stop = slice.stop + def ll_stringslice_startstop(s1, start, stop): if stop >= len(s1.chars): if start == 0: return s1 Modified: pypy/branch/getslice/pypy/rpython/ootypesystem/rstr.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/ootypesystem/rstr.py (original) +++ pypy/branch/getslice/pypy/rpython/ootypesystem/rstr.py Fri Oct 10 20:14:02 2008 @@ -198,9 +198,7 @@ def ll_stringslice_startonly(s, start): return s.ll_substring(start, s.ll_strlen() - start) - def ll_stringslice(s, slice): - start = slice.start - stop = slice.stop + def ll_stringslice_startstop(s, start, stop): length = s.ll_strlen() if stop > length: stop = length Modified: pypy/branch/getslice/pypy/rpython/rlist.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/rlist.py (original) +++ pypy/branch/getslice/pypy/rpython/rlist.py Fri Oct 10 20:14:02 2008 @@ -370,24 +370,14 @@ if r_lst1.item_repr.lowleveltype not in (Char, UniChar): raise TyperError('"lst += string" only supported with a list ' 'of chars or unichars') - rs = r_lst1.rtyper.type_system.rslice string_repr = r_lst1.rtyper.type_system.rstr.string_repr + v_lst1 = hop.inputarg(r_lst1, arg=0) + v_str2 = hop.inputarg(string_repr, arg=3) + kind, vlist = hop.decompose_slice_args() c_strlen = hop.inputconst(Void, string_repr.ll.ll_strlen) c_stritem = hop.inputconst(Void, string_repr.ll.ll_stritem_nonneg) - r_slic = hop.args_r[2] - v_lst1, v_str2, v_slice = hop.inputargs(r_lst1, string_repr, r_slic) - if r_slic == rs.startonly_slice_repr: - hop.gendirectcall(ll_extend_with_str_slice_startonly, - v_lst1, v_str2, c_strlen, c_stritem, v_slice) - elif r_slic == rs.startstop_slice_repr: - hop.gendirectcall(ll_extend_with_str_slice, - v_lst1, v_str2, c_strlen, c_stritem, v_slice) - elif r_slic == rs.minusone_slice_repr: - hop.gendirectcall(ll_extend_with_str_slice_minusone, - v_lst1, v_str2, c_strlen, c_stritem) - else: - raise TyperError('lst += str[:] does not support slices with %r' % - (r_slic,)) + ll_fn = globals()['ll_extend_with_str_slice_%s' % kind] + hop.gendirectcall(ll_fn, v_lst1, v_str2, c_strlen, c_stritem, *vlist) return v_lst1 class __extend__(pairtype(AbstractListRepr, AbstractCharRepr)): @@ -775,9 +765,8 @@ i += 1 j += 1 -def ll_extend_with_str_slice(lst, s, getstrlen, getstritem, slice): - start = slice.start - stop = slice.stop +def ll_extend_with_str_slice_startstop(lst, s, getstrlen, getstritem, + start, stop): len1 = lst.ll_length() len2 = getstrlen(s) ll_assert(start >= 0, "unexpectedly negative str slice start") Modified: pypy/branch/getslice/pypy/rpython/rstr.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/rstr.py (original) +++ pypy/branch/getslice/pypy/rpython/rstr.py Fri Oct 10 20:14:02 2008 @@ -330,22 +330,14 @@ rtype_getitem_idx_key = rtype_getitem_idx -##class __extend__(pairtype(AbstractStringRepr, AbstractSliceRepr)): +class __extend__(AbstractStringRepr): -## def rtype_getitem((r_str, r_slic), hop): -## string_repr = r_str.repr -## rslice = hop.rtyper.type_system.rslice - -## if r_slic == rslice.startonly_slice_repr: -## v_str, v_start = hop.inputargs(string_repr, rslice.startonly_slice_repr) -## return hop.gendirectcall(r_str.ll.ll_stringslice_startonly, v_str, v_start) -## if r_slic == rslice.startstop_slice_repr: -## v_str, v_slice = hop.inputargs(string_repr, rslice.startstop_slice_repr) -## return hop.gendirectcall(r_str.ll.ll_stringslice, v_str, v_slice) -## if r_slic == rslice.minusone_slice_repr: -## v_str, v_ignored = hop.inputargs(string_repr, rslice.minusone_slice_repr) -## return hop.gendirectcall(r_str.ll.ll_stringslice_minusone, v_str) -## raise TyperError(r_slic) + def rtype_getslice(r_str, hop): + string_repr = r_str.repr + v_str = hop.inputarg(string_repr, arg=0) + kind, vlist = hop.decompose_slice_args() + ll_fn = getattr(r_str.ll, 'll_stringslice_%s' % (kind,)) + return hop.gendirectcall(ll_fn, v_str, *vlist) class __extend__(pairtype(AbstractStringRepr, AbstractStringRepr)): def rtype_add((r_str1, r_str2), hop): Modified: pypy/branch/getslice/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/rtyper.py (original) +++ pypy/branch/getslice/pypy/rpython/rtyper.py Fri Oct 10 20:14:02 2008 @@ -578,7 +578,7 @@ def translate_op_extend_with_str_slice(self, hop): r_arg1 = hop.args_r[0] - r_arg2 = hop.args_r[1] + r_arg2 = hop.args_r[3] return pair(r_arg1, r_arg2).rtype_extend_with_str_slice(hop) def translate_op_extend_with_char_count(self, hop): @@ -589,9 +589,6 @@ def translate_op_newtuple(self, hop): return self.type_system.rtuple.rtype_newtuple(hop) - def translate_op_newslice(self, hop): - return rslice.rtype_newslice(hop) - def translate_op_instantiate1(self, hop): from pypy.rpython.lltypesystem import rclass if not isinstance(hop.s_result, annmodel.SomeInstance): Modified: pypy/branch/getslice/pypy/translator/transform.py ============================================================================== --- pypy/branch/getslice/pypy/translator/transform.py (original) +++ pypy/branch/getslice/pypy/translator/transform.py Fri Oct 10 20:14:02 2008 @@ -57,10 +57,10 @@ # lst += string[x:y] # --> -# b = getitem(string, slice) +# b = getslice(string, x, y) # c = inplace_add(lst, b) # --> -# c = extend_with_str_slice(lst, string, slice) +# c = extend_with_str_slice(lst, x, y, string) def transform_extend_with_str_slice(self, block_subset): """Transforms lst += string[x:y] to extend_with_str_slice""" @@ -68,16 +68,15 @@ slice_sources = {} # maps b to [string, slice] in the above notation for i in range(len(block.operations)): op = block.operations[i] - if (op.opname == 'getitem' and - self.gettype(op.args[0]) is str and - self.gettype(op.args[1]) is slice): + if (op.opname == 'getslice' and + self.gettype(op.args[0]) is str): slice_sources[op.result] = op.args elif (op.opname == 'inplace_add' and op.args[1] in slice_sources and self.gettype(op.args[0]) is list): - v_string, v_slice = slice_sources[op.args[1]] + v_string, v_x, v_y = slice_sources[op.args[1]] new_op = SpaceOperation('extend_with_str_slice', - [op.args[0], v_string, v_slice], + [op.args[0], v_x, v_y, v_string], op.result) block.operations[i] = new_op From witulski at codespeak.net Fri Oct 10 20:29:09 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Fri, 10 Oct 2008 20:29:09 +0200 (CEST) Subject: [pypy-svn] r58937 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081010182909.1F12F16A03D@codespeak.net> Author: witulski Date: Fri Oct 10 20:29:08 2008 New Revision: 58937 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: memory access works Mov REG, Stack added + Tests Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Fri Oct 10 20:29:08 2008 @@ -1,4 +1,4 @@ -from pypy.jit.codegen.x86_64.objmodel import IntVar, Register8, Register64, Immediate8, Immediate32, Immediate64 +from pypy.jit.codegen.x86_64.objmodel import IntVar, Register8, Register64, Immediate8, Immediate32, Immediate64, Stack64 # Mapping from 64Bit-Register to coding (Rex.W or Rex.B , ModRM) REGISTER_MAP = { @@ -74,7 +74,15 @@ # used in imul (extra long opcode) if not extra == None: self.write(extra) - self.write_modRM_byte(mod, modrm2, modrm1) + self.write_modRM_byte(mod, modrm2, modrm1) + elif isinstance(arg2.location, Stack64): + self.write_rex_byte(rexW, rexR, rexX, rexB) + self.write(opcode) + # exchanged mod1,mod2, dont know why :) + self.write_modRM_byte(mod, modrm1, modrm2) + # no scale, no index, base = rsp + self.write_SIB(0, 4, 4) + self.writeImm32(arg2.location.offset) return quadreg_instr @@ -119,8 +127,8 @@ modrm1 = md1 modrm2 = md2 rexW = W - rexR = R - rexX = X + rexR = R #not used? + rexX = X #not used? rexB = B # TODO: other cases e.g memory as operand # FIXME: rexB? @@ -170,7 +178,7 @@ #TODO: support all combinations # The opcodes differs depending on the operands # Params: - # W (64bit Operands), R (extends reg field), X (extend Index(SIB) field), B (extends r/m field, Base(SIB) field, opcode reg field), + # W (Width, 64bit Operands), R (Register, extends reg field), X (IndeX, extend Index(SIB) field), B (Base, extends r/m field, Base(SIB) field, opcode reg field), # Opcode, mod, modrm1, modrm2, tttn(JUMPS), extraopcode # FIXME: rexB is set @@ -193,8 +201,9 @@ _MOV_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, None, "\xC7", 3, None, 0) _MOV_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x89", 3, None, None) _MOV_QWREG_IMM64 = make_two_operand_instr_with_alternate_encoding(1,0,0,None,"B8",None,None) + _MOV_QWREG_STACK = make_two_operand_instr( 1, 0, 0, None, "\x8B", 2, None, 4)#4 =RSP - _IDIV_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xF7", 3, None, 7) + _IDIV_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xF7", 3, None, 7) _IMUL_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x0F", 3, None, None, None, "\xAF") _IMUL_QWREG_IMM32 = make_two_operand_instr( 1, None, 0, None, "\x69", 3, None, "sameReg") @@ -412,6 +421,10 @@ byte = mod << 6 | (reg << 3) | rm self.write(chr(byte)) + def write_SIB(self, scale, index, base): + byte = scale << 6 | (index << 3) | base + self.write(chr(byte)) + # calc. the "Two's complement" # and return as pos. hex value. # This method is used to calc jump displ. Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py Fri Oct 10 20:29:08 2008 @@ -6,22 +6,25 @@ # The to_string method is used to choose the right # method inside the assembler -class Register64(object): +class Location(object): + pass + +class Register64(Location): def __init__(self, reg): self.reg = reg -class Register8(object): +class Register8(Location): def __init__(self, reg): self.reg = reg -class Stack64(object): +class Stack64(Location): def __init__(self, offset): self.offset = offset class IntVar(model.GenVar): def __init__(self, location): self.location = location - assert isinstance(location, Register64) or isinstance(location, Register8) or isinstance(location, Stack64) + assert isinstance(location, Location) def to_string(self): if isinstance(self.location, Stack64): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Fri Oct 10 20:29:08 2008 @@ -1,6 +1,6 @@ from pypy.jit.codegen import model from pypy.rlib.objectmodel import specialize -from pypy.jit.codegen.x86_64.objmodel import IntVar, Register64, Register8, Immediate8, Immediate32, Immediate64 +from pypy.jit.codegen.x86_64.objmodel import IntVar, Register64, Register8, Immediate8, Immediate32, Immediate64, Stack64 from pypy.jit.codegen.x86_64.codebuf import InMemoryCodeBuilder #TODO: understand llTypesystem from pypy.rpython.lltypesystem import llmemory, lltype @@ -73,7 +73,8 @@ MC_SIZE = 65536 #FIXME: The MemCodeBuild. is not opend in an _open method - def __init__(self, used_registers=[]): + def __init__(self, stackdepth, used_registers=[]): + self.stackdepth = stackdepth self.mc = InMemoryCodeBuilder(self.MC_SIZE) #callee-saved registers are commented out self.freeregisters ={ @@ -101,15 +102,21 @@ @specialize.arg(1) def genop1(self, opname, gv_arg): + if isinstance(gv_arg, model.GenVar) and isinstance(gv_arg.location, Stack64): + move_back_to_register(gv_arg) genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg) @specialize.arg(1) def genop2(self, opname, gv_arg1, gv_arg2): + if isinstance(gv_arg1, model.GenVar) and isinstance(gv_arg1.location, Stack64): + move_back_to_register(gv_arg1) + if isinstance(gv_arg2, model.GenVar) and isinstance(gv_arg2.location, Stack64): + move_back_to_register(gv_arg2) genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg1, gv_arg2) - op_int_add = make_two_argument_method("ADD") + op_int_add = make_two_argument_method("ADD") #TODO: use inc op_int_and = make_two_argument_method("AND") op_int_dec = make_one_argument_method("DEC") #for debuging op_int_inc = make_one_argument_method("INC") #for debuging @@ -119,7 +126,7 @@ op_int_or = make_two_argument_method("OR") op_int_push = make_one_argument_method("PUSH") #for debuging op_int_pop = make_one_argument_method("POP") #for debuging - op_int_sub = make_two_argument_method("SUB") + op_int_sub = make_two_argument_method("SUB") # TODO: use DEC op_int_xor = make_two_argument_method("XOR") # TODO: support reg8 @@ -241,7 +248,7 @@ def jump(self, gv_condition, args_for_jump_gv): # the targetbuilder must know the registers(live vars) # of the calling block - targetbuilder = Builder(args_for_jump_gv) + targetbuilder = Builder(self.stackdepth, args_for_jump_gv) self.mc.CMP(gv_condition, Immediate32(value)) self.mc.JNE(targetbuilder.mc.tell()) return targetbuilder @@ -257,6 +264,7 @@ self.mc.MOV(IntVar(Register64("rax")), gv_returnvar) self.mc.RET() self._close() + assert self.stackdepth == 0 #FIXME: uses 32bit displ # if the label is greater than 32bit @@ -320,26 +328,44 @@ # TODO: alloc strategy # TODO: support 8bit reg. alloc - # just greddy + # just greddy spilling def spill_register(self): # take the first gv which is not # on the stack gv_to_spill = None for i in range(len(known_gv)): - if not known_gv[i].location_type == "Stack64": + if not isinstance(known_gv[i].location, Stack64): gv_to_spill = self.known_gv[i] break # there must be genVars which are # inside an register so: - assert not gv_to_spill==None - - #TODO: update Stackposition + assert isinstance(gv_to_spill.location, Register64) + self.stackdepth = self.stackdepth +1 self.mc.PUSH(gv_to_spill) new_gv = IntVar(Register64(gv_to_spill.location.reg)) - gv_to_spill.location = Stack64(42) #XXX + gv_to_spill.location = Stack64(self.stackdepth) return new_gv - + + def move_back_to_register(a_spilled_gv): + # if top of stack + if a_spilled_gv.location.offset == self.stackdepth: + gv_new = self.allocate_register() + self.mc.POP(gv_new) + self.stackdepth = self.stackdepth -1 + assert self.stackdepth >= 0 + #update all offsets + for i in range(len(known_gv)): + if isinstance(known_gv[i].location, Stack64): + known_gv[i].location.offset = known_gv[i].location.offset -1 + a_spilled_gv = gv_new + # TODO: free gv_new (no double values in known_gv + # else access the memory + # FIXME: if this genVar becomes the top of stack it will never be pushed + else: + pass + + class RX86_64GenOp(model.AbstractRGenOp): @@ -365,7 +391,7 @@ arg_tokens, res_token = sigtoken #print "arg_tokens:",arg_tokens inputargs_gv = [] - builder = Builder() + builder = Builder(0) # stackdepth = 0 # TODO: Builder._open() entrypoint = builder.mc.tell() # from http://www.x86-64.org/documentation/abi.pdf Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Fri Oct 10 20:29:08 2008 @@ -2,6 +2,7 @@ from pypy.rpython.lltypesystem import lltype from pypy.jit.codegen.x86_64.rgenop import RX86_64GenOp, Label from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTestsDirect +from pypy.jit.codegen.x86_64.objmodel import IntVar, Stack64 #from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTestsCompile # for the individual tests see @@ -10,14 +11,32 @@ def skip(self): py.test.skip("not implemented yet") +# pushes/pos some values and than uses a mem access to access the stack +def make_mem_func(rgenop): + sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) + builder, gv_mem_func, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "mem_op") + builder.start_writing() + builder.genop1("int_inc", gv_y) + builder.genop1("int_inc", gv_y) + builder.genop1("int_inc", gv_y) + builder.genop1("int_push", gv_y) + builder.genop1("int_inc", gv_y) + builder.genop1("int_push", gv_y) + builder.mc.MOV(gv_x, IntVar(Stack64(8))) # rsp+8(bytes) (stack position of the first push) + builder.genop1("int_pop", gv_y) + builder.genop1("int_pop", gv_y) + builder.finish_and_return(sigtoken, gv_x) + builder.end() + return gv_mem_func + def make_push_pop(rgenop): sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed], lltype.Signed)) builder, gv_push_pop, [gv_x] = rgenop.newgraph(sigtoken, "push_pop") builder.start_writing() - gv_x = builder.genop1("int_push", gv_x) - gv_x = builder.genop1("int_inc", gv_x) - gv_x = builder.genop1("int_inc", gv_x) - gv_x = builder.genop1("int_pop", gv_x) + builder.genop1("int_push", gv_x) + builder.genop1("int_inc", gv_x) + builder.genop1("int_inc", gv_x) + builder.genop1("int_pop", gv_x) builder.finish_and_return(sigtoken, gv_x) builder.end() return gv_push_pop @@ -442,6 +461,17 @@ fnptr = self.cast(pp_func,1) result = fnptr(1) assert result == 1 + result = fnptr(42) + assert result == 42 + + # return + def test_memory_access(self): + mem_func = make_mem_func(self.RGenOp()) + fnptr = self.cast(mem_func,2) + result = fnptr(0,0) + assert result == 3 + result = fnptr(-1,2) + assert result == 5 # def test_invert(self): # inv_function = make_one_op_instr(self.RGenOp(),"int_invert") From fijal at codespeak.net Sat Oct 11 10:08:39 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 11 Oct 2008 10:08:39 +0200 (CEST) Subject: [pypy-svn] r58943 - pypy/branch/2.5-merge/pypy/lib Message-ID: <20081011080839.C592E16A115@codespeak.net> Author: fijal Date: Sat Oct 11 10:08:37 2008 New Revision: 58943 Modified: pypy/branch/2.5-merge/pypy/lib/_locale.py Log: re-enable locale Modified: pypy/branch/2.5-merge/pypy/lib/_locale.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/_locale.py (original) +++ pypy/branch/2.5-merge/pypy/lib/_locale.py Sat Oct 11 10:08:37 2008 @@ -3,8 +3,6 @@ Support for POSIX locales. """ -raise ImportError("_locale.py is still incomplete") - from ctypes import (Structure, POINTER, create_string_buffer, c_ubyte, c_int, c_char_p, c_wchar_p) from ctypes_support import standard_c_lib as libc @@ -44,17 +42,14 @@ del LocaleConfigure del config -try: - class LanginfoConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) - nl_item = SimpleType('nl_item') - config = configure(LanginfoConfigure) - nl_item = config['nl_item'] - del LanginfoConfigure - del config - HAS_LANGINFO = True -except: - HAS_LANGINFO = False +class LanginfoConfigure: + _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) + nl_item = SimpleType('nl_item') +config = configure(LanginfoConfigure) +nl_item = config['nl_item'] +del LanginfoConfigure +del config +HAS_LANGINFO = True # Ubuntu Gusty i386 structure class lconv(Structure): From fijal at codespeak.net Sat Oct 11 10:16:04 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 11 Oct 2008 10:16:04 +0200 (CEST) Subject: [pypy-svn] r58945 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081011081604.B020416A1B3@codespeak.net> Author: fijal Date: Sat Oct 11 10:16:02 2008 New Revision: 58945 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_unicodedata.py Log: Fix imports Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_unicodedata.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_unicodedata.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_unicodedata.py Sat Oct 11 10:16:02 2008 @@ -6,7 +6,7 @@ """#" import unittest, test.test_support -import hashlib +import hashlib, sys encoding = 'utf-8' From pedronis at codespeak.net Sat Oct 11 10:31:05 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 11 Oct 2008 10:31:05 +0200 (CEST) Subject: [pypy-svn] r58946 - pypy/build/bot2 Message-ID: <20081011083105.474D016A13A@codespeak.net> Author: pedronis Date: Sat Oct 11 10:31:03 2008 New Revision: 58946 Modified: pypy/build/bot2/TODO Log: some other TODOs Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Sat Oct 11 10:31:03 2008 @@ -1,6 +1,8 @@ - buildbot Nightly scheduler that can pick a uniform revision server side and with support for specifying possibly branches +- sort ! failures first + - improve summary page (defined in pypybuildbot/summary.page), support querying/slicing by builders, formatting and css @@ -18,3 +20,5 @@ - wire windows slave IN-PROGRESS +- convention for naming and coalescing alternative builders for the same build + From fijal at codespeak.net Sat Oct 11 10:51:32 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 11 Oct 2008 10:51:32 +0200 (CEST) Subject: [pypy-svn] r58947 - pypy/branch/2.5-merge/pypy/interpreter Message-ID: <20081011085132.13FC616A123@codespeak.net> Author: fijal Date: Sat Oct 11 10:51:31 2008 New Revision: 58947 Modified: pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py Log: Not catch NotImplementedError here Modified: pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py Sat Oct 11 10:51:31 2008 @@ -104,6 +104,8 @@ except MemoryError: next_instr = self.handle_asynchronous_error(ec, self.space.w_MemoryError) + except NotImplementedError: + raise except RuntimeError, e: if we_are_translated(): # stack overflows should be the only kind of RuntimeErrors From arigo at codespeak.net Sat Oct 11 11:10:39 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 11:10:39 +0200 (CEST) Subject: [pypy-svn] r58948 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081011091039.416231684E0@codespeak.net> Author: arigo Date: Sat Oct 11 11:10:36 2008 New Revision: 58948 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Support for inlining a function that contains a malloc into all direct_call callers. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sat Oct 11 11:10:36 2008 @@ -14,11 +14,11 @@ if not isinstance(MALLOCTYPE, lltype.GcStruct): raise CannotRemoveThisType self.MALLOCTYPE = MALLOCTYPE + self.check_no_destructor() self.names_and_types = [] self.name2index = {} self.initialize_type(MALLOCTYPE) #self.immutable_struct = MALLOCTYPE._hints.get('immutable') - self.check_no_destructor() def check_no_destructor(self): STRUCT = self.MALLOCTYPE @@ -202,7 +202,9 @@ def __init__(self, graphs, verbose=False): self.graphs = graphs self.graphbuilders = {} - self.specialized_graphs = FrameKeyCache() + self.specialized_graphs = {} + self.inline_and_remove = {} # {graph: op_to_remove} + self.inline_and_remove_seen = {} # set of (graph, op_to_remove) self.malloctypedescs = {} self.count_virtualized = 0 self.verbose = verbose @@ -211,8 +213,7 @@ log.mallocv('removed %d mallocs so far' % (self.count_virtualized,)) return self.count_virtualized - def find_all_mallocs(self, graph): - result = [] + def enum_all_mallocs(self, graph): for block in graph.iterblocks(): for op in block.operations: if op.opname == 'malloc': @@ -222,31 +223,35 @@ except CannotRemoveThisType: pass else: - result.append((block, op)) - return result + yield (block, op) + elif op.opname == 'direct_call': + fobj = op.args[0].value._obj + graph = getattr(fobj, 'graph', None) + if graph in self.inline_and_remove: + yield (block, op) def remove_mallocs_once(self): self.flush_failed_specializations() prev = self.count_virtualized + count_inline_and_remove = len(self.inline_and_remove) for graph in self.graphs: - all_blocks = None - all_mallocs = self.find_all_mallocs(graph) - for block, op in all_mallocs: - if all_blocks is None: - all_blocks = set(graph.iterblocks()) - if block not in all_blocks: - continue # this block was removed from the graph - # by a previous try_remove_malloc() - if self.try_remove_malloc(graph, block, op): - all_blocks = None # graph mutated - progress = self.report_result() - prev - return progress + seen = {} + while True: + for block, op in self.enum_all_mallocs(graph): + if op.result not in seen: + seen[op.result] = True + if self.try_remove_malloc(graph, block, op): + break # graph mutated, restart enum_all_mallocs() + else: + break # enum_all_mallocs() exhausted, graph finished + progress1 = self.report_result() - prev + progress2 = len(self.inline_and_remove) - count_inline_and_remove + return progress1 or bool(progress2) def flush_failed_specializations(self): - cache = self.specialized_graphs.content - for key, (mode, specgraph) in cache.items(): + for key, (mode, specgraph) in self.specialized_graphs.items(): if mode == 'fail': - del cache[key] + del self.specialized_graphs[key] def getmalloctypedesc(self, MALLOCTYPE): try: @@ -256,35 +261,56 @@ return dsc def try_remove_malloc(self, graph, block, op): + if (graph, op) in self.inline_and_remove_seen: + return False # no point in trying again graphbuilder = GraphBuilder(self) if graph in self.graphbuilders: graphbuilder.initialize_from_old_builder(self.graphbuilders[graph]) graphbuilder.start_from_a_malloc(block, op.result) try: graphbuilder.propagate_specializations() - except (CannotVirtualize, ForcedInline), e: - if self.verbose: - log.mallocv('%s %s: %s' % (op.result, e.__class__.__name__, e)) + except CannotVirtualize, e: + self.logresult(op, 'failed', e) + return False + except ForcedInline, e: + self.logresult(op, 'forces inlining', e) + self.inline_and_remove[graph] = op + self.inline_and_remove_seen[graph, op] = True return False else: - if self.verbose: - log.mallocv('%s removed' % (op.result,)) + self.logresult(op, 'removed') graphbuilder.finished_removing_malloc() self.graphbuilders[graph] = graphbuilder self.count_virtualized += 1 return True + def logresult(self, op, msg, exc=None): # only for nice log outputs + if self.verbose: + if exc is None: + exc = '' + else: + exc = ': %s' % (exc,) + chain = [] + while True: + chain.append(str(op.result)) + if op.opname != 'direct_call': + break + fobj = op.args[0].value._obj + op = self.inline_and_remove[fobj.graph] + log.mallocv('%s %s%s' % ('->'.join(chain), msg, exc)) + def get_specialized_graph(self, graph, nodelist): assert len(graph.getargs()) == len(nodelist) if is_trivial_nodelist(nodelist): return 'trivial', graph nodes = dict(zip(graph.getargs(), nodelist)) virtualframe = VirtualFrame(graph.startblock, 0, nodes) + key = virtualframe.getfrozenkey() try: - return self.specialized_graphs.getitem(virtualframe) + return self.specialized_graphs[key] except KeyError: - self.build_specialized_graph(graph, virtualframe, nodelist) - return self.specialized_graphs.getitem(virtualframe) + self.build_specialized_graph(graph, key, nodelist) + return self.specialized_graphs[key] def build_specialized_graph(self, graph, key, nodelist): graph2 = copygraph(graph) @@ -296,48 +322,27 @@ specgraph = graph2 specgraph.name += '_mallocv' specgraph.startblock = specblock - self.specialized_graphs.setitem(key, ('call', specgraph)) + self.specialized_graphs[key] = ('call', specgraph) try: graphbuilder.propagate_specializations() except ForcedInline, e: if self.verbose: log.mallocv('%s inlined: %s' % (graph.name, e)) - self.specialized_graphs.setitem(key, ('inline', None)) + self.specialized_graphs[key] = ('inline', None) except CannotVirtualize, e: if self.verbose: log.mallocv('%s failing: %s' % (graph.name, e)) - self.specialized_graphs.setitem(key, ('fail', None)) + self.specialized_graphs[key] = ('fail', None) else: self.graphbuilders[specgraph] = graphbuilder self.graphs.append(specgraph) -class FrameKeyCache(object): - - def __init__(self): - self.content = {} - - def get(self, virtualframe): - key = virtualframe.getfrozenkey() - return self.content.get(key) - - def getitem(self, virtualframe): - key = virtualframe.getfrozenkey() - return self.content[key] - - def setitem(self, virtualframe, value): - key = virtualframe.getfrozenkey() - self.content[key] = value - - def update(self, other): - self.content.update(other.content) - - class GraphBuilder(object): def __init__(self, mallocv): self.mallocv = mallocv - self.specialized_blocks = FrameKeyCache() + self.specialized_blocks = {} self.pending_specializations = [] def initialize_from_old_builder(self, oldbuilder): @@ -350,6 +355,7 @@ return spec.specblock def start_from_a_malloc(self, block, v_result): + assert v_result in [op.result for op in block.operations] nodes = {} for v in block.inputargs: nodes[v] = RuntimeSpecNode(v, v.concretetype) @@ -366,16 +372,17 @@ srcblock.exitswitch = specblock.exitswitch srcblock.recloseblock(*specblock.exits) - def get_specialized_block(self, virtualframe): - specblock = self.specialized_blocks.get(virtualframe) + def get_specialized_block(self, virtualframe, v_expand_malloc=None): + key = virtualframe.getfrozenkey() + specblock = self.specialized_blocks.get(key) if specblock is None: orgblock = virtualframe.sourceblock assert len(orgblock.exits) != 0 - spec = BlockSpecializer(self) + spec = BlockSpecializer(self, v_expand_malloc) spec.initialize_renamings(virtualframe) self.pending_specializations.append(spec) specblock = spec.specblock - self.specialized_blocks.setitem(virtualframe, specblock) + self.specialized_blocks[key] = specblock return specblock def propagate_specializations(self): @@ -469,15 +476,20 @@ specblock = link.target else: if len(link.target.exits) == 0: # return or except block + if len(link.target.inputargs) != 1: + raise CannotVirtualize("except block") if currentframe.callerframe is None: - raise ForcedInline("return or except block") + raise ForcedInline("return block") newframe = currentframe.return_to_caller(link.target, targetnodes) + v_expand_malloc = None else: newframe = VirtualFrame(link.target, 0, targetnodes, callerframe=currentframe.callerframe) + v_expand_malloc = self.v_expand_malloc rtnodes = newframe.find_rt_nodes() - specblock = self.graphbuilder.get_specialized_block(newframe) + specblock = self.graphbuilder.get_specialized_block(newframe, + v_expand_malloc) linkargs = [self.renamings[rtnode] for rtnode in rtnodes] newlink = Link(linkargs, specblock) @@ -572,6 +584,7 @@ c = Constant(FIELDTYPE._defl()) c.concretetype = FIELDTYPE self.renamings[fieldnode] = c + self.v_expand_malloc = None # done return [] else: return self.handle_default(op) @@ -585,8 +598,16 @@ assert nb_args == len(graph.getargs()) newnodes = [self.getnode(v) for v in op.args[1:]] myframe = self.get_updated_frame(op) - argnodes = copynodes(newnodes, flagreadonly=myframe.find_vt_nodes()) mallocv = self.graphbuilder.mallocv + + if op.result is self.v_expand_malloc: + # move to inlining the callee, and continue looking for the + # malloc to expand in the callee's graph + op_to_remove = mallocv.inline_and_remove[graph] + self.v_expand_malloc = op_to_remove.result + return self.handle_inlined_call(myframe, graph, newnodes) + + argnodes = copynodes(newnodes, flagreadonly=myframe.find_vt_nodes()) kind, newgraph = mallocv.get_specialized_graph(graph, argnodes) if kind == 'trivial': return self.handle_default(op) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sat Oct 11 11:10:36 2008 @@ -44,6 +44,7 @@ t.view() # to detect missing keepalives and broken intermediate graphs, # we do the loop ourselves instead of calling remove_simple_mallocs() + maxiter = 100 mallocv = MallocVirtualizer(t.graphs, verbose=True) while True: progress = mallocv.remove_mallocs_once() @@ -57,6 +58,8 @@ assert res == expected_result if not progress: break + maxiter -= 1 + assert maxiter > 0, "infinite loop?" self.check_malloc_removed(graph, expected_mallocs, expected_calls) return graph @@ -228,6 +231,39 @@ A() self.check(fn7, [], [], None, expected_mallocs=1) # don't remove + def test_call_to_allocating(self): + class A: + pass + def g(n): + a = A() + a.x = n + a.y = n + 1 + return a + def fn8(n): + a = g(n) + return a.x * a.y + self.check(fn8, [int], [6], 42, expected_calls=0) # inlined + + def test_many_calls_to_allocating(self): + class A: + pass + def g(n): + a = A() + a.x = n + return a + def h(n): + a = g(n) + a.y = n + return a + def i(n): + a = h(n) + a.y += 1 + return a + def fn9(n): + a = i(n) + return a.x * a.y + self.check(fn9, [int], [6], 42, expected_calls=0) # inlined + class TestLLTypeMallocRemoval(BaseMallocRemovalTest): type_system = 'lltype' From arigo at codespeak.net Sat Oct 11 11:25:14 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 11:25:14 +0200 (CEST) Subject: [pypy-svn] r58951 - pypy/branch/getslice/pypy/objspace/flow Message-ID: <20081011092514.DC72416A135@codespeak.net> Author: arigo Date: Sat Oct 11 11:25:14 2008 New Revision: 58951 Modified: pypy/branch/getslice/pypy/objspace/flow/objspace.py Log: Re-enable newslice in the flow objspace, for geninterp. Modified: pypy/branch/getslice/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/flow/objspace.py (original) +++ pypy/branch/getslice/pypy/objspace/flow/objspace.py Sat Oct 11 11:25:14 2008 @@ -103,7 +103,7 @@ return Constant(slice(self.unwrap(w_start), self.unwrap(w_stop), self.unwrap(w_step))) - raise Exception("not supported in RPython: extended slicing") + return self.do_operation('newslice', w_start, w_stop, w_step) def wrap(self, obj): if isinstance(obj, (Variable, Constant)): From arigo at codespeak.net Sat Oct 11 11:38:41 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 11:38:41 +0200 (CEST) Subject: [pypy-svn] r58952 - in pypy/branch/getslice/pypy/objspace/flow: . test Message-ID: <20081011093841.10CEF16A166@codespeak.net> Author: arigo Date: Sat Oct 11 11:38:40 2008 New Revision: 58952 Modified: pypy/branch/getslice/pypy/objspace/flow/operation.py pypy/branch/getslice/pypy/objspace/flow/test/test_objspace.py Log: Improve test and fix it. Modified: pypy/branch/getslice/pypy/objspace/flow/operation.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/flow/operation.py (original) +++ pypy/branch/getslice/pypy/objspace/flow/operation.py Sat Oct 11 11:38:40 2008 @@ -134,6 +134,16 @@ def lshift_ovf(x, y): return ovfcheck_lshift(x, y) +# slicing: operator.{get,set,del}slice() don't support b=None or c=None +def do_getslice(a, b, c): + return a[b:c] + +def do_setslice(a, b, c, d): + a[b:c] = d + +def do_delslice(a, b, c): + del a[b:c] + # ____________________________________________________________ # The following table can list several times the same operation name, @@ -190,6 +200,9 @@ ('delete', delete), ('userdel', userdel), ('buffer', buffer), + ('getslice', do_getslice), + ('setslice', do_setslice), + ('delslice', do_delslice), # --- operations added by graph transformations --- ('neg_ovf', neg_ovf), ('abs_ovf', abs_ovf), Modified: pypy/branch/getslice/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/branch/getslice/pypy/objspace/flow/test/test_objspace.py Sat Oct 11 11:38:40 2008 @@ -852,11 +852,29 @@ py.test.raises(RuntimeError, "self.codetest(f)") def test_getslice_constfold(self): - def f(): + def check(f, expected): + graph = self.codetest(f) + assert graph.startblock.operations == [] + [link] = graph.startblock.exits + assert link.target is graph.returnblock + assert isinstance(link.args[0], Constant) + assert link.args[0].value == expected + + def f1(): + s = 'hello' + return s[:-2] + check(f1, 'hel') + + def f2(): s = 'hello' - return s[:3] - graph = self.codetest(f) - assert not self.all_operations(graph) + return s[:] + check(f2, 'hello') + + def f3(): + s = 'hello' + return s[-3:] + check(f3, 'llo') + class TestFlowObjSpaceDelay(Base): def setup_class(cls): From xoraxax at codespeak.net Sat Oct 11 11:46:49 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 11 Oct 2008 11:46:49 +0200 (CEST) Subject: [pypy-svn] r58953 - in pypy/build/benchmem: . testing Message-ID: <20081011094649.C53DB16A12E@codespeak.net> Author: xoraxax Date: Sat Oct 11 11:46:48 2008 New Revision: 58953 Modified: pypy/build/benchmem/runbench.py pypy/build/benchmem/smaps.py pypy/build/benchmem/testing/test_benchtool.py Log: (hpk, xoraxax) Add new basesize benchmark, refactor parsing again. Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Sat Oct 11 11:46:48 2008 @@ -6,16 +6,55 @@ and append results to a log file ("bench.log" by default). """ -import py import os, sys, re +from subprocess import Popen, PIPE + +import py import smaps + optparse = py.compat.optparse mydir = py.magic.autopath().dirpath() benchmarkdir = mydir.join("benchmark") + class BenchRunner: SEPBENCH = "=" * 80 - + + def log(self, *args): + print " ".join(map(str, args)) + + +class BenchRunnerBaseSize(BenchRunner): + def __init__(self, executable, logpath, options): + self.executable = executable + self.executable_full_path = py.path.local.sysfind(executable) + self.logpath = py.path.local(logpath) + self.logstream = self.logpath.open("a") + self.options = options + + def write_benchheader(self): + print >>self.logstream, self.SEPBENCH + print >>self.logstream, "#benchtype=basesize" + print >>self.logstream, "#executable=%s" %(str(self.executable ),) + print >>self.logstream + + def run(self): + cmds = [str(self.executable_full_path), '-c', '''import sys; sys.stdout.write("F"); sys.stdout.flush(); raw_input()'''] + self.log("running %r" % (cmds, )) + popen = Popen(cmds, shell=False, stdin=PIPE, stdout=PIPE, close_fds=True) + self.write_benchheader() + rec = smaps.SmapsRecorder(popen.pid, self.logstream) + #print "Reading", popen.pid + line = popen.stdout.read(1).strip() + assert line == 'F' + rec.snapshot() + #print "Writing" + popen.stdin.write("\n") + popen.stdin.flush() + #print "Waiting" + popen.wait() + + class BenchRunnerObjsize(BenchRunner): def __init__(self, executable, fsname, logpath, options): self.executable = executable @@ -25,9 +64,6 @@ self.logstream = self.logpath.open("a") self.tmpdir = py.path.local.make_numbered_dir(prefix="bench") self.options = options - - def log(self, *args): - print " ".join(map(str, args)) def makebench(self, name): arglist = str(self.options.numiter) @@ -131,62 +167,61 @@ def parse(self, logpath): f = logpath.open() - for result in Result.parse(f): - #print "parsed", result - self.results.append(result) + self.results.extend(self.yield_results(f)) f.close() - -class Result(object): - @classmethod - def parseheader(cls, iterline): + + def parseheader(self, stream_iter): kw = {} - while 1: - lineno, line = iterline() + for lineno, line in stream_iter: if not line.strip(): - return kw + return kw assert line.startswith("#"), line key, value = map(str.strip, line[1:].split("=")) kw[key] = value - @classmethod - def parse(cls, f): - def genline(): - lineno = 1 - while 1: - yield lineno, f.readline() - lineno += 1 - iterline = genline().next - lineno, line = iterline() - while not f.closed: - if not line: - break + def yield_results(self, stream): + stream_iter = enumerate(stream) + for lineno, line in stream_iter: line = line.rstrip() if line != BenchRunner.SEPBENCH: - print "ignoring %d: %s" %(lineno, line) - lineno, line = iterline() - continue - kw = cls.parseheader(iterline) - - benchtype = kw.pop('benchtype') - if benchtype == "sizes": - snapshots = [] - lineno, line = iterline() - while 1: - mappings = [] - while line != smaps.SmapsRecorder.SEPSNAPSHOT: - mappings.append(smaps.Mapping(line)) - lineno, line = iterline() - #print "reading", line.strip() - snapshots.append(Snapshot(mappings)) - lineno, line = iterline() - #print "reading %d: %s" %(lineno, line) - if not line or line.startswith(BenchRunner.SEPBENCH): - break - #print "yielding result", kw['benchname'] - yield ObjsizeResult(snapshots, **kw) + print "ignoring %d: %s" % (lineno, line) + else: + break + while 1: + kw = self.parseheader(stream_iter) + if kw is None: + break + yield parse_result(stream_iter, kw) + +def parse_result(stream, kw): + chosen_cls = None + benchtype = kw.pop('benchtype') + for scls in Result.__subclasses__(): + if scls.benchtype == benchtype: + chosen_cls = scls + break + assert chosen_cls is not None, 'Unknown benchtype ' + repr(benchtype) + return chosen_cls.parse(stream, kw) + + +class Result(object): + @classmethod + def parse(cls, lnstream, kw): + snapshots = [] + mappings = [] + for lineno, line in lnstream: + line = line.rstrip() + if line == smaps.SmapsRecorder.SEPSNAPSHOT: + snapshots.append(Snapshot(mappings)) + mappings = [] + elif line == BenchRunner.SEPBENCH: + break else: - assert 0, benchtype - + mappings.append(smaps.Mapping(line)) + continue + return cls(snapshots, **kw) + + class ObjsizeResult(Result): benchtype = "sizes" def __init__(self, snapshots, executable, benchpath, benchname, benchargs): @@ -210,6 +245,15 @@ dirty = mapping.private_dirty + mapping.shared_dirty assert mapping.rss == dirty + clean + +class BasesizeResult(Result): + benchtype = 'basesize' + def __init__(self, snapshots, executable): + self.snapshot = snapshots[0] + assert len(snapshots) == 1 + self.executable = executable + + class Snapshot(object): def __init__(self, mappings): assert mappings Modified: pypy/build/benchmem/smaps.py ============================================================================== --- pypy/build/benchmem/smaps.py (original) +++ pypy/build/benchmem/smaps.py Sat Oct 11 11:46:48 2008 @@ -2,7 +2,7 @@ import py class SmapsRecorder: - SEPSNAPSHOT = "-"*80 + "\n" + SEPSNAPSHOT = "-"*80 def __init__(self, pid, stream): self.stream = stream @@ -40,7 +40,7 @@ headline = nextheadline except StopIteration: append_attrs(attrs) - self.stream.write(self.SEPSNAPSHOT) + self.stream.write(self.SEPSNAPSHOT + "\n") self.stream.flush() Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Sat Oct 11 11:46:48 2008 @@ -158,3 +158,18 @@ val2 = getattr(snap.mappings[1], name) assert sumval == val1 + val2 + +def test_basesize(): + tmpdir = py.test.ensuretemp("basesize") + benchlog = tmpdir.join("log") + class Options: pass + runner = runbench.BenchRunnerBaseSize("python2.5", benchlog, Options()) + runner.run() + resultset = runbench.ResultSet() + resultset.parse(benchlog) + + assert len(resultset.results) == 1 + result = resultset.results[0] + assert result.benchtype == 'basesize' + assert result.executable.endswith('python2.5') + assert result.snapshot.heap_private() > 42 From arigo at codespeak.net Sat Oct 11 11:54:51 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 11:54:51 +0200 (CEST) Subject: [pypy-svn] r58954 - pypy/branch/getslice/pypy/translator/test Message-ID: <20081011095451.29F8616A1A6@codespeak.net> Author: arigo Date: Sat Oct 11 11:54:50 2008 New Revision: 58954 Modified: pypy/branch/getslice/pypy/translator/test/test_simplify.py Log: More robustness against the ExceptionInfo's __str__ which might have or not have the str of the captured exception in it. Modified: pypy/branch/getslice/pypy/translator/test/test_simplify.py ============================================================================== --- pypy/branch/getslice/pypy/translator/test/test_simplify.py (original) +++ pypy/branch/getslice/pypy/translator/test/test_simplify.py Sat Oct 11 11:54:50 2008 @@ -200,7 +200,7 @@ transform_dead_op_vars(graph, t) interp = LLInterpreter(t.rtyper) e = py.test.raises(LLException, 'interp.eval_graph(graph, [])') - assert 'ValueError' in str(e) + assert 'ValueError' in str(e.value) class TestDetectListComprehension: def check(self, f1, expected): From arigo at codespeak.net Sat Oct 11 12:01:58 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 12:01:58 +0200 (CEST) Subject: [pypy-svn] r58955 - pypy/branch/getslice/pypy/rpython Message-ID: <20081011100158.55DD0169FE0@codespeak.net> Author: arigo Date: Sat Oct 11 12:01:57 2008 New Revision: 58955 Modified: pypy/branch/getslice/pypy/rpython/rtuple.py Log: (antocuni, arigo) Reimplement slicing for tuples. Modified: pypy/branch/getslice/pypy/rpython/rtuple.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/rtuple.py (original) +++ pypy/branch/getslice/pypy/rpython/rtuple.py Sat Oct 11 12:01:57 2008 @@ -241,18 +241,22 @@ index = v_index.value return r_tup.getitem(hop.llops, v_tuple, index) -##class __extend__(pairtype(AbstractTupleRepr, AbstractSliceRepr)): +class __extend__(AbstractTupleRepr): -## def rtype_getitem((r_tup, r_slice), hop): -## v_tup = hop.inputarg(r_tup, arg=0) -## s_slice = hop.args_s[1] -## start, stop, step = s_slice.constant_indices() -## indices = range(len(r_tup.items_r))[start:stop:step] -## assert len(indices) == len(hop.r_result.items_r) - -## items_v = [r_tup.getitem_internal(hop.llops, v_tup, i) -## for i in indices] -## return hop.r_result.newtuple(hop.llops, hop.r_result, items_v) + def rtype_getslice(r_tup, hop): + s_start = hop.args_s[1] + s_stop = hop.args_s[2] + assert s_start.is_immutable_constant(),"tuple slicing: needs constants" + assert s_stop.is_immutable_constant(), "tuple slicing: needs constants" + start = s_start.const + stop = s_stop.const + indices = range(len(r_tup.items_r))[start:stop] + assert len(indices) == len(hop.r_result.items_r) + + v_tup = hop.inputarg(r_tup, arg=0) + items_v = [r_tup.getitem_internal(hop.llops, v_tup, i) + for i in indices] + return hop.r_result.newtuple(hop.llops, hop.r_result, items_v) class __extend__(pairtype(AbstractTupleRepr, Repr)): def rtype_contains((r_tup, r_item), hop): From arigo at codespeak.net Sat Oct 11 12:12:08 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 12:12:08 +0200 (CEST) Subject: [pypy-svn] r58956 - pypy/branch/getslice/pypy/rpython/test Message-ID: <20081011101208.AF8B916A170@codespeak.net> Author: arigo Date: Sat Oct 11 12:12:05 2008 New Revision: 58956 Modified: pypy/branch/getslice/pypy/rpython/test/test_rtyper.py Log: (antocuni, arigo) Remove a test which no longer makes sense. Modified: pypy/branch/getslice/pypy/rpython/test/test_rtyper.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/test/test_rtyper.py (original) +++ pypy/branch/getslice/pypy/rpython/test/test_rtyper.py Sat Oct 11 12:12:05 2008 @@ -27,35 +27,6 @@ key2 = rtyper.makekey(stup2) assert key1 != key2 -def test_slice_reprkeys(): - one = annmodel.SomeInteger(nonneg=True) - one.const = 1 - three = annmodel.SomeInteger(nonneg=True) - three.const = 3 - minusone = annmodel.SomeInteger() - minusone.const = -1 - none = annmodel.s_None - - startonly = annmodel.SomeSlice(one, none, none) - startonly2 = annmodel.SomeSlice(one, none, one) - startonly3 = annmodel.SomeSlice(three, none, one) - - startstop = annmodel.SomeSlice(one, one, none) - startstop2 = annmodel.SomeSlice(one, one, one) - startstop3 = annmodel.SomeSlice(one, three, none) - - minusone_slice = annmodel.SomeSlice(none, minusone, none) - minusone_slice2 = annmodel.SomeSlice(none, minusone, one) - - assert startonly.rtyper_makekey() == startonly2.rtyper_makekey() == startonly3.rtyper_makekey() - assert startstop.rtyper_makekey() == startstop2.rtyper_makekey() == startstop3.rtyper_makekey() - assert minusone_slice.rtyper_makekey() == minusone_slice2.rtyper_makekey() - - assert startonly.rtyper_makekey() != startstop.rtyper_makekey() - assert startonly.rtyper_makekey() != minusone_slice.rtyper_makekey() - assert minusone_slice.rtyper_makekey() != startstop.rtyper_makekey() - - def test_simple(): def dummyfn(x): return x+1 From antocuni at codespeak.net Sat Oct 11 12:16:18 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 11 Oct 2008 12:16:18 +0200 (CEST) Subject: [pypy-svn] r58957 - pypy/build/bot2/codespeak-html Message-ID: <20081011101618.921FC16A18E@codespeak.net> Author: antocuni Date: Sat Oct 11 12:16:17 2008 New Revision: 58957 Modified: pypy/build/bot2/codespeak-html/index.html Log: change the host name also in the title Modified: pypy/build/bot2/codespeak-html/index.html ============================================================================== --- pypy/build/bot2/codespeak-html/index.html (original) +++ pypy/build/bot2/codespeak-html/index.html Sat Oct 11 12:16:17 2008 @@ -2,7 +2,7 @@ -Welcome to Wyvern's PyPy Buildbot +Welcome to codespeak's PyPy Buildbot From fijal at codespeak.net Sat Oct 11 12:32:22 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 11 Oct 2008 12:32:22 +0200 (CEST) Subject: [pypy-svn] r58958 - in pypy/branch/cbuild-refactor/pypy: rpython/tool tool tool/test translator translator/c/test translator/goal translator/platform translator/platform/test translator/tool translator/tool/test Message-ID: <20081011103222.C74B716A1C9@codespeak.net> Author: fijal Date: Sat Oct 11 12:32:21 2008 New Revision: 58958 Modified: pypy/branch/cbuild-refactor/pypy/rpython/tool/rffi_platform.py pypy/branch/cbuild-refactor/pypy/tool/gcc_cache.py pypy/branch/cbuild-refactor/pypy/tool/test/test_gcc_cache.py pypy/branch/cbuild-refactor/pypy/translator/c/test/test_boehm.py pypy/branch/cbuild-refactor/pypy/translator/c/test/test_stackless.py pypy/branch/cbuild-refactor/pypy/translator/driver.py pypy/branch/cbuild-refactor/pypy/translator/goal/translate.py pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py Log: (pedronis, fijal) Shuffle stuff around, shave some more yaks Modified: pypy/branch/cbuild-refactor/pypy/rpython/tool/rffi_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/rpython/tool/rffi_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/rpython/tool/rffi_platform.py Sat Oct 11 12:32:21 2008 @@ -561,6 +561,21 @@ gcv = sysconfig.get_config_vars() return gcv['INCLUDEPY'] +def check_boehm(platform=None, cache={}): + if platform is None: + from pypy.translator.platform import platform + try: + return cache[platform] + except KeyError: + class CConfig: + _compilation_info_ = ExternalCompilationInfo( + includes=['gc/gc.h'], + platform=platform, + ) + HAS = Has('GC_init') + cache[platform] = configure(CConfig)['HAS'] + return cache[platform] + if __name__ == '__main__': doc = """Example: Modified: pypy/branch/cbuild-refactor/pypy/tool/gcc_cache.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/tool/gcc_cache.py (original) +++ pypy/branch/cbuild-refactor/pypy/tool/gcc_cache.py Sat Oct 11 12:32:21 2008 @@ -1,8 +1,7 @@ from pypy.tool.autopath import pypydir -from pypy.translator.tool.cbuild import build_executable +from pypy.translator.platform import platform, CompilationError from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.translator.tool.cbuild import CompilationError from pypy.tool.compat import md5 import py @@ -20,9 +19,9 @@ try: return path.read() except py.error.Error: - result = eci.platform.execute(build_executable(c_files, eci)) - path.write(result) - return result + result = platform.execute(platform.compile(c_files, eci)) + path.write(result.out) + return result.out def try_compile_cache(c_files, eci): path = cache_file_path(c_files, eci, 'try_compile_cache') @@ -32,7 +31,7 @@ data = '' if not (data.startswith('True') or data.startswith('FAIL\n')): try: - build_executable(c_files, eci) + platform.compile(c_files, eci) data = 'True' except CompilationError, e: data = 'FAIL\n%s\n' % (e,) @@ -42,4 +41,4 @@ else: assert data.startswith('FAIL\n') msg = data[len('FAIL\n'):] - raise CompilationError(msg.strip()) + raise CompilationError(msg.strip(), '') Modified: pypy/branch/cbuild-refactor/pypy/tool/test/test_gcc_cache.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/tool/test/test_gcc_cache.py (original) +++ pypy/branch/cbuild-refactor/pypy/tool/test/test_gcc_cache.py Sat Oct 11 12:32:21 2008 @@ -24,7 +24,8 @@ path = cache_file_path([f], eci, 'build_executable_cache') if path.check(): path.remove() - assert build_executable_cache([f], eci) == "3\n" + res = build_executable_cache([f], eci) + assert res == "3\n" assert build_executable_cache([f], eci) == "3\n" eci2 = ExternalCompilationInfo(include_dirs=[str(dir2)]) assert build_executable_cache([f], eci2) == "42\n" Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_boehm.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_boehm.py Sat Oct 11 12:32:21 2008 @@ -2,12 +2,12 @@ from pypy.translator.translator import TranslationContext from pypy.rpython.lltypesystem import lltype from pypy.rpython.memory.test import snippet -from pypy.translator.tool.cbuild import check_boehm_presence +from pypy.rpython.tool.rffi_platform import check_boehm from pypy.translator.c.genc import CExtModuleBuilder from pypy import conftest def setup_module(mod): - if not check_boehm_presence(): + if not check_boehm(): py.test.skip("Boehm GC not present") class AbstractGCTestClass(object): Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_stackless.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_stackless.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_stackless.py Sat Oct 11 12:32:21 2008 @@ -20,8 +20,8 @@ import py py.test.skip("stackless + refcounting doesn't work any more for now") elif cls.gcpolicy == "boehm": - from pypy.translator.tool.cbuild import check_boehm_presence - if not check_boehm_presence(): + from pypy.rpython.tool.rffi_platform import check_boehm + if not check_boehm(): py.test.skip("Boehm GC not present") def wrap_stackless_function(self, fn): Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/driver.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/driver.py Sat Oct 11 12:32:21 2008 @@ -457,13 +457,10 @@ def possibly_check_for_boehm(self): if self.config.translation.gc == "boehm": - from pypy.translator.tool.cbuild import check_boehm_presence - from pypy.translator.tool.cbuild import CompilationError - try: - check_boehm_presence(noerr=False) - except CompilationError, e: + from pypy.rpython.tool.rffi_platform import check_boehm + if not check_boehm(self.translator.platform): i = 'Boehm GC not installed. Try e.g. "translate.py --gc=hybrid"' - raise CompilationError('%s\n--------------------\n%s' % (e, i)) + raise Exception(i) def task_database_c(self): translator = self.translator @@ -516,7 +513,7 @@ if self.exe_name is not None: exename = mkexename(self.c_entryp) newexename = self.compute_exe_name() - shutil.copy(exename, newexename) + shutil.copy(str(exename), str(newexename)) self.c_entryp = newexename self.log.info("created: %s" % (self.c_entryp,)) Modified: pypy/branch/cbuild-refactor/pypy/translator/goal/translate.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/goal/translate.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/goal/translate.py Sat Oct 11 12:32:21 2008 @@ -163,7 +163,7 @@ translating=True) # apply the platform settings - set_platform(config, translateconfig.platform) + set_platform(translateconfig, config) # apply the optimization level settings set_opt_level(config, translateconfig.opt) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Sat Oct 11 12:32:21 2008 @@ -3,7 +3,11 @@ platform. """ -import sys +import sys, py + +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("platform") +py.log.setconsumer("platform", ansi_log) class CompilationError(Exception): def __init__(self, out, err): @@ -32,11 +36,32 @@ def __repr__(self): return '<%s cc=%s>' % (self.__class__.__name__, self.cc) + def __hash__(self): + return hash(self.__class__.__name__) + + def __ne__(self, other): + return not self == other + + def __eq__(self, other): + return (self.__class__ is other.__class__ and + self.__dict__ == other.__dict__) + def check___thread(self): return True + if sys.platform == 'linux2': from pypy.translator.platform.linux import Linux host = Linux() else: xxx + +platform = host + +def set_platform(new_platform, cc): + global platform + assert new_platform == 'host' + log.msg("Setting platform to %r cc=%s" % (new_platform,cc)) + # XXX fix + platform = host + Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sat Oct 11 12:32:21 2008 @@ -1,12 +1,9 @@ import py, os from pypy.translator.platform import Platform, CompilationError, ExecutionResult +from pypy.translator.platform import log from subprocess import PIPE, Popen -from pypy.tool.ansi_print import ansi_log -log = py.log.Producer("cbuild") -py.log.setconsumer("cbuild", ansi_log) - def _run_subprocess(executable, args, env=None): if isinstance(args, str): args = str(executable) + ' ' + args @@ -22,17 +19,21 @@ return pipe.returncode, stdout, stderr class Linux(Platform): - link_extra = ['-lpthread'] + link_extra = ['-pthread'] + cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] def __init__(self, cc='gcc'): self.cc = cc - def _args_from_eci(self, cfiles, eci): + def _compile_args_from_eci(self, eci): include_dirs = ['-I%s' % (idir,) for idir in eci.include_dirs] + return (self.cflags + list(eci.compile_extra) + include_dirs) + + def _link_args_from_eci(self, eci): library_dirs = ['-L%s' % (ldir,) for ldir in eci.library_dirs] libraries = ['-l%s' % (lib,) for lib in eci.libraries] - return (include_dirs + [str(f) for f in cfiles] + - library_dirs + libraries + self.link_extra) + return (library_dirs + libraries + self.link_extra + + list(eci.link_extra)) def _args_for_shared(self, args): return ['-shared'] + args @@ -40,20 +41,30 @@ def compile(self, cfiles, eci, outputfilename=None, standalone=True): cfiles = [py.path.local(f) for f in cfiles] cfiles += [py.path.local(f) for f in eci.separate_module_files] - args = self._args_from_eci(cfiles, eci) + compile_args = self._compile_args_from_eci(eci) if outputfilename is None: outputfilename = cfiles[0].purebasename exe_name = py.path.local(os.path.join(str(cfiles[0].dirpath()), outputfilename)) if not standalone: exe_name += '.so' - args += ['-o', str(exe_name)] - if not standalone: - args = self._args_for_shared(args) - log.execute(self.cc + ' ' + ' '.join(args)) - returncode, stdout, stderr = _run_subprocess(self.cc, args) + ofiles = [] + for cfile in cfiles: + ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) + return self._link(self.cc, ofiles, self._link_args_from_eci(eci), + standalone, exe_name) + + def _compile_c_file(self, cc, cfile, compile_args): + oname = cfile.new(ext='o') + args = ['-c'] + compile_args + [str(cfile), '-o', str(oname)] + self._execute_c_compiler(cc, args, oname) + return oname + + def _execute_c_compiler(self, cc, args, outname): + log.execute(cc + ' ' + ' '.join(args)) + returncode, stdout, stderr = _run_subprocess(cc, args) if returncode != 0: - errorfile = exe_name.new(ext='errors') + errorfile = outname.new(ext='errors') errorfile.write(stderr) stderrlines = stderr.splitlines() for line in stderrlines[:5]: @@ -61,6 +72,13 @@ if len(stderrlines) > 5: log.ERROR('...') raise CompilationError(stdout, stderr) + + def _link(self, cc, ofiles, link_args, standalone, exe_name): + args = [str(ofile) for ofile in ofiles] + link_args + args += ['-o', str(exe_name)] + if not standalone: + args = self._args_for_shared(args) + self._execute_c_compiler(cc, args, exe_name) return exe_name def execute(self, executable, args=None, env=None): Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Sat Oct 11 12:32:21 2008 @@ -1,7 +1,7 @@ import py, sys from pypy.tool.udir import udir -from pypy.translator.platform import host, CompilationError +from pypy.translator.platform import host, CompilationError, Platform from pypy.translator.tool.cbuild import ExternalCompilationInfo def test_simple_enough(): @@ -20,6 +20,30 @@ assert res.err == '' assert res.returncode == 0 +def test_two_files(): + cfile = udir.join('test_two_files.c') + cfile.write(''' + #include + int func(); + int main() + { + printf("%d\\n", func()); + return 0; + } + ''') + cfile2 = udir.join('implement1.c') + cfile2.write(''' + int func() + { + return 42; + } + ''') + executable = host.compile([cfile, cfile2], ExternalCompilationInfo()) + res = host.execute(executable) + assert res.out == '42\n' + assert res.err == '' + assert res.returncode == 0 + def test_nice_errors(): cfile = udir.join('test_nice_errors.c') cfile.write('') @@ -72,3 +96,16 @@ executable = host.compile([c_file], eci) res = host.execute(executable) assert res.out.startswith('4.0') + + +def test_equality(): + class X(Platform): + def __init__(self): + pass + class Y(Platform): + def __init__(self, x): + self.x = x + + assert X() == X() + assert Y(3) == Y(3) + assert Y(2) != Y(3) Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Sat Oct 11 12:32:21 2008 @@ -90,8 +90,7 @@ assert isinstance(value, (list, tuple)) setattr(self, name, tuple(value)) if platform is None: - from pypy.rlib import pyplatform - platform = pyplatform.platform + from pypy.translator.platform import platform self.platform = platform def from_compiler_flags(cls, flags): @@ -489,40 +488,8 @@ extra_preargs=self.link_extra, library_dirs=self.eci.library_dirs) -def build_executable(*args, **kwds): - noerr = kwds.pop('noerr', False) - compiler = CCompiler(*args, **kwds) - compiler.build(noerr=noerr) - return str(compiler.outputfilename) - -def check_boehm_presence(noerr=True): - from pypy.tool.udir import udir - try: - cfile = udir.join('check_boehm.c') - cfname = str(cfile) - cfile = cfile.open('w') - cfile.write(""" -#include - -int main() { - return 0; -} -""") - cfile.close() - if sys.platform == 'win32': - eci = ExternalCompilationInfo(libraries=['gc_pypy']) - else: - eci = ExternalCompilationInfo(libraries=['gc']) - build_executable([cfname], eci, noerr=noerr) - except CompilationError: - if noerr: - return False - else: - raise - else: - return True - def check_under_under_thread(): + xxx from pypy.tool.udir import udir cfile = py.path.local(autopath.this_dir).join('__thread_test.c') fsource = cfile.open('r') Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py Sat Oct 11 12:32:21 2008 @@ -125,38 +125,6 @@ class Stuff: - def test_platform(self): - from pypy.rlib.pyplatform import Platform - class Expected(Exception): - pass - - class X(Platform): - def get_compiler(self): - raise Expected - - def execute(self): - return 3 - - eci = ExternalCompilationInfo(platform=X()) - try: - build_executable([self.modfile], eci) - except Expected: - pass - else: - py.test.fail("Did not raise") - assert eci.platform.execute() == 3 - - def test_platform_equality(self): - from pypy.rlib.pyplatform import Platform - class X(Platform): - pass - class Y(Platform): - def __init__(self, x): - self.x = x - - assert X() == X() - assert Y(3) == Y(3) - assert Y(2) != Y(3) def checkscratchbox(self): if not py.path.local('/scratchbox/login').check(): From arigo at codespeak.net Sat Oct 11 12:38:39 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 12:38:39 +0200 (CEST) Subject: [pypy-svn] r58959 - pypy/branch/2.5-merge/pypy/objspace/std/test Message-ID: <20081011103839.4707216A111@codespeak.net> Author: arigo Date: Sat Oct 11 12:38:38 2008 New Revision: 58959 Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_dictmultiobject.py Log: Make the test slightly less obscure. Modified: pypy/branch/2.5-merge/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/branch/2.5-merge/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/branch/2.5-merge/pypy/objspace/std/test/test_dictmultiobject.py Sat Oct 11 12:38:38 2008 @@ -33,13 +33,16 @@ def test_string_subclass_via_setattr(self): skip("issue383") + class A(object): + pass class S(str): def __hash__(self): return 123 + a = A() s = S("abc") - setattr(s, s, 42) - assert s.__dict__.keys()[0] is s - assert getattr(s, s) == 42 + setattr(a, s, 42) + assert a.__dict__.keys()[0] is s + assert getattr(a, s) == 42 class TestW_DictSharing(test_dictobject.TestW_DictObject): From arigo at codespeak.net Sat Oct 11 13:05:07 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 13:05:07 +0200 (CEST) Subject: [pypy-svn] r58960 - pypy/branch/2.5-merge/pypy/interpreter Message-ID: <20081011110507.E124B16A1C7@codespeak.net> Author: arigo Date: Sat Oct 11 13:05:07 2008 New Revision: 58960 Modified: pypy/branch/2.5-merge/pypy/interpreter/gateway.py Log: One missing re-raise of NotImplementedError :-( Modified: pypy/branch/2.5-merge/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/gateway.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/gateway.py Sat Oct 11 13:05:07 2008 @@ -572,6 +572,8 @@ raise OperationError(space.w_KeyboardInterrupt, space.w_None) except MemoryError: raise OperationError(space.w_MemoryError, space.w_None) + except NotImplementedError, e: + raise except (RuntimeError, DescrMismatch), e: raise OperationError(space.w_RuntimeError, space.wrap("internal error: " + str(e))) From arigo at codespeak.net Sat Oct 11 13:05:31 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 13:05:31 +0200 (CEST) Subject: [pypy-svn] r58961 - in pypy/branch/2.5-merge/pypy: interpreter interpreter/test module/__builtin__ Message-ID: <20081011110531.BD18816A1C7@codespeak.net> Author: arigo Date: Sat Oct 11 13:05:31 2008 New Revision: 58961 Modified: pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py pypy/branch/2.5-merge/pypy/interpreter/test/test_compiler.py pypy/branch/2.5-merge/pypy/interpreter/test/test_exec.py pypy/branch/2.5-merge/pypy/module/__builtin__/compiling.py Log: (antocuni, arigo) Add tests that correspond to removing code :-) This cancels rev 11877, which was a hack for CPython compliance. It turns out that CPython 2.5 changed. Modified: pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/pyopcode.py Sat Oct 11 13:05:31 2008 @@ -1348,15 +1348,7 @@ else: raise TypeError("exec: arg 1 must be a string, file, " "or code object") - try: - prog = compile(prog, filename, 'exec', compile_flags, 1) - except SyntaxError, e: # exec SyntaxErrors have filename==None - if len(e.args) == 2: - msg, loc = e.args - loc1 = (None,) + loc[1:] - e.args = msg, loc1 - e.filename = None - raise e + prog = compile(prog, filename, 'exec', compile_flags, 1) return (prog, globals, locals) ''', filename=__file__) Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_compiler.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_compiler.py Sat Oct 11 13:05:31 2008 @@ -581,6 +581,15 @@ """) assert space.float_w(w_result) == 0 + def test_filename_in_syntaxerror(self): + e = py.test.raises(OperationError, self.compiler.compile, """if 1: + 'unmatched_quote + """, 'hello_world', 'exec', 0) + ex = e.value + space = self.space + assert ex.match(space, space.w_SyntaxError) + assert 'hello_world' in space.str_w(space.str(ex.w_value)) + class TestPyCCompiler(BaseTestCompiler): def setup_method(self, method): Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_exec.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_exec.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_exec.py Sat Oct 11 13:05:31 2008 @@ -192,3 +192,12 @@ exec "y=n" in m # NOTE: this doesn't work in CPython 2.4 assert m.result == {'x': 'm', 'y': 'n'} + def test_filename(self): + try: + exec "'unmatched_quote" + except SyntaxError, msg: + assert msg.filename == '' + try: + eval("'unmatched_quote") + except SyntaxError, msg: + assert msg.filename == '' Modified: pypy/branch/2.5-merge/pypy/module/__builtin__/compiling.py ============================================================================== --- pypy/branch/2.5-merge/pypy/module/__builtin__/compiling.py (original) +++ pypy/branch/2.5-merge/pypy/module/__builtin__/compiling.py Sat Oct 11 13:05:31 2008 @@ -60,22 +60,10 @@ if (space.is_true(space.isinstance(w_code, space.w_str)) or space.is_true(space.isinstance(w_code, space.w_unicode))): - try: - w_code = compile(space, - space.call_method(w_code, 'lstrip', - space.wrap(' \t')), - "", "eval") - except OperationError, e: - if e.match(space, space.w_SyntaxError): - e_value_w = space.viewiterable(e.w_value) - if len(e_value_w) == 2: - e_loc_w = space.viewiterable(e_value_w[1]) - e.w_value = space.newtuple([e_value_w[0], - space.newtuple([space.w_None]+ - e_loc_w[1:])]) - raise e - else: - raise + w_code = compile(space, + space.call_method(w_code, 'lstrip', + space.wrap(' \t')), + "", "eval") codeobj = space.interpclass_w(w_code) if not isinstance(codeobj, PyCode): From arigo at codespeak.net Sat Oct 11 13:11:38 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 13:11:38 +0200 (CEST) Subject: [pypy-svn] r58962 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081011111138.662F716A163@codespeak.net> Author: arigo Date: Sat Oct 11 13:11:36 2008 New Revision: 58962 Added: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_deque.py - copied, changed from r58959, pypy/branch/2.5-merge/lib-python/2.5.2/test/test_deque.py Log: (antocuni, arigo) - remove all the test_deque changes, which don't make sense any more - add a gc_collect() Copied: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_deque.py (from r58959, pypy/branch/2.5-merge/lib-python/2.5.2/test/test_deque.py) ============================================================================== --- pypy/branch/2.5-merge/lib-python/2.5.2/test/test_deque.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_deque.py Sat Oct 11 13:11:36 2008 @@ -475,6 +475,7 @@ p = proxy(d) self.assertEqual(str(p), str(d)) d = None + test_support.gc_collect() self.assertRaises(ReferenceError, str, p) def test_strange_subclass(self): From arigo at codespeak.net Sat Oct 11 13:27:38 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 13:27:38 +0200 (CEST) Subject: [pypy-svn] r58963 - in pypy/branch/2.5-merge/pypy/lib: . app_test Message-ID: <20081011112738.95730169FBD@codespeak.net> Author: arigo Date: Sat Oct 11 13:27:36 2008 New Revision: 58963 Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_deque_extra.py pypy/branch/2.5-merge/pypy/lib/collections.py Log: (antocuni, arigo) Fix CPython's test_deque. Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_deque_extra.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/app_test/test_deque_extra.py (original) +++ pypy/branch/2.5-merge/pypy/lib/app_test/test_deque_extra.py Sat Oct 11 13:27:36 2008 @@ -11,6 +11,7 @@ def setup_method(self,method): from pypy.lib.collections import deque + self.deque = deque self.d = deque(range(n)) def test_deque(self): @@ -24,24 +25,35 @@ def test_deque_iter(self): it = iter(self.d) - assert len(it) == n + raises(TypeError, len, it) assert it.next() == 0 - assert len(it) == n-1 self.d.pop() - raises(RuntimeError,it.next) - assert len(it) == 0 - assert list(it) == [] - + raises(RuntimeError, it.next) + def test_deque_reversed(self): it = reversed(self.d) - assert len(it) == n + raises(TypeError, len, it) assert it.next() == n-1 - assert len(it) == n-1 assert it.next() == n-2 - assert len(it) == n-2 self.d.pop() - raises(RuntimeError,it.next) - assert len(it) == 0 - assert list(it) == [] + raises(RuntimeError, it.next) + + def test_deque_remove(self): + d = self.d + raises(ValueError, d.remove, "foobar") + + def test_mutate_during_remove(self): + # Handle evil mutator + class MutateCmp: + def __init__(self, deque, result): + self.deque = deque + self.result = result + def __eq__(self, other): + self.deque.clear() + return self.result - + for match in (True, False): + d = self.deque(['ab']) + d.extend([MutateCmp(d, match), 'c']) + raises(IndexError, d.remove, 'c') + assert len(d) == 0 Modified: pypy/branch/2.5-merge/pypy/lib/collections.py ============================================================================== --- pypy/branch/2.5-merge/pypy/lib/collections.py (original) +++ pypy/branch/2.5-merge/pypy/lib/collections.py Sat Oct 11 13:27:36 2008 @@ -113,15 +113,10 @@ def remove(self, value): # Need to be defensive for mutating comparisons - i = 0 - while i < len(self): + for i in range(len(self)): if self[i] == value: - if i < len(self): - del self[i] - return - else: - raise IndexError("deque mutated during remove()") - i += 1 + del self[i] + return raise ValueError("deque.remove(x): x not in deque") def rotate(self, n=1): @@ -316,9 +311,6 @@ def __iter__(self): return self - def __len__(self): - return self.counter - class defaultdict(dict): def __init__(self, *args, **kwds): From cfbolz at codespeak.net Sat Oct 11 13:28:26 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 11 Oct 2008 13:28:26 +0200 (CEST) Subject: [pypy-svn] r58964 - in pypy/dist/pypy/module/unicodedata: . test Message-ID: <20081011112826.53E97169FBD@codespeak.net> Author: cfbolz Date: Sat Oct 11 13:28:25 2008 New Revision: 58964 Modified: pypy/dist/pypy/module/unicodedata/__init__.py pypy/dist/pypy/module/unicodedata/interp_ucd.py pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py Log: (iko, cfbolz): Use the same unicode-database that CPython 2.5 uses. Write a test that checks some stuff from the unicode database against the underlying Python's. Modified: pypy/dist/pypy/module/unicodedata/__init__.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/__init__.py (original) +++ pypy/dist/pypy/module/unicodedata/__init__.py Sat Oct 11 13:28:25 2008 @@ -6,7 +6,7 @@ interpleveldefs = { 'unidata_version' : 'space.wrap(interp_ucd.ucd.version)', 'ucd_3_2_0' : 'space.wrap(interp_ucd.ucd_3_2_0)', - #'ucd_4_1_0' : 'space.wrap(interp_ucd.ucd_4_1_0)', + 'ucd_4_1_0' : 'space.wrap(interp_ucd.ucd_4_1_0)', #'ucd_5_0_0' : 'space.wrap(interp_ucd.ucd_5_0_0)', 'ucd' : 'space.wrap(interp_ucd.ucd)', '__doc__' : "space.wrap('unicode character database')", Modified: pypy/dist/pypy/module/unicodedata/interp_ucd.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/interp_ucd.py (original) +++ pypy/dist/pypy/module/unicodedata/interp_ucd.py Sat Oct 11 13:28:25 2008 @@ -289,5 +289,5 @@ ucd_3_2_0 = UCD(unicodedb_3_2_0) ucd_4_1_0 = UCD(unicodedb_4_1_0) ucd_5_0_0 = UCD(unicodedb_5_0_0) -ucd = ucd_3_2_0 +ucd = ucd_4_1_0 Modified: pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py (original) +++ pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py Sat Oct 11 13:28:25 2008 @@ -3,8 +3,24 @@ class AppTestUnicodeData: def setup_class(cls): + import random, unicodedata + seed = random.getrandbits(32) + print "random seed: ", seed + random.seed(seed) space = gettestobjspace(usemodules=('unicodedata',)) cls.space = space + charlist_w = [] + for i in range(2000): + chr = unichr(random.randrange(65536)) + try: + w_tup = space.newtuple([ + space.wrap(chr), + space.wrap(unicodedata.name(chr)) + ]) + charlist_w.append(w_tup) + except ValueError: + pass + cls.w_charlist = space.newlist(charlist_w) def test_hangul_syllables(self): import unicodedata @@ -70,3 +86,10 @@ except ValueError: pass raises(KeyError, unicodedata.lookup, charname) + + def test_random_charnames(self): + import unicodedata + for chr, name in self.charlist: + assert unicodedata.name(chr) == name + assert unicodedata.lookup(name) == chr + From cfbolz at codespeak.net Sat Oct 11 13:30:09 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 11 Oct 2008 13:30:09 +0200 (CEST) Subject: [pypy-svn] r58965 - in pypy/dist/pypy/module/unicodedata: . test Message-ID: <20081011113009.A3C2516A0C8@codespeak.net> Author: cfbolz Date: Sat Oct 11 13:30:08 2008 New Revision: 58965 Added: pypy/dist/pypy/module/unicodedata/compression.py (contents, props changed) pypy/dist/pypy/module/unicodedata/test/test_compression.py (contents, props changed) Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Log: (iko, cfbolz): Write a trivial compression algorithm for the unicode names. Use it in the script that generates the unicode database. Added: pypy/dist/pypy/module/unicodedata/compression.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/unicodedata/compression.py Sat Oct 11 13:30:08 2008 @@ -0,0 +1,55 @@ + +def build_compression_table(stringlist): + # build compression code table + BITS = 8 + codes = {} + chars = {} + # put all characters into code + for value in stringlist: + for char in value: + chars.setdefault(char, len(chars)) + + # fill code with larger strings + for value in stringlist: + start = 0 + for start in range(len(value)): + for stop in range(start + 1, len(value)): + codes[value[start:stop]] = codes.get(value[start:stop], 0) + 1 + + # take most common strings + s = [(freq, code) for (code, freq) in codes.iteritems() if len(code) > 1] + s.sort() + s.reverse() + common = chars.keys() + [code for freq, code in s[:2 ** BITS - len(chars)]] + assert len(common) <= 2 ** BITS + + finalcodes = {} + for code in common: + assert code not in finalcodes + finalcodes[code] = len(finalcodes) + return finalcodes, common + + +def compress(codetable, s): + start = 0 + result = "" + while start < len(s): + stop = start + 1 + while stop <= len(s): + if s[start:stop + 1] not in codetable: + result += chr(codetable[s[start:stop]]) + break + else: + stop += 1 + else: + # true only for last symbol + result += chr(codetable[s[start:]]) + start = stop + + return result + +def uncompress(codelist, s): + result = [] + for sym in s: + result.append(codelist[ord(sym)]) + return "".join(result) Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/generate_unicodedb.py (original) +++ pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Sat Oct 11 13:30:08 2008 @@ -1,5 +1,8 @@ #!/usr/bin/env python +import pprint +import compression + MAXUNICODE = 0x10FFFF # the value of sys.maxunicode of wide Python builds class Fraction: @@ -309,6 +312,23 @@ print >> outfile, 'def mirrored(code): return _get_record(code)[3] & %d != 0'% IS_MIRRORED print >> outfile, 'def combining(code): return _get_record(code)[4]' +def write_character_names(outfile, table): + # Compressed Character names + names = [table[code].name for code in range(len(table)) if table[code].name] + codetable, codelist = compression.build_compression_table(names) + print >> outfile, '_charnames = {' + for code in range(len(table)): + name = table[code].name + if name: + print >> outfile, '%r: %r,' % ( + code, compression.compress(codetable, name)) + print >> outfile, "}\n" + print >> outfile, "_codetable =", + pprint.pprint(codetable, outfile) + print >> outfile, "_codelist =", + pprint.pprint(codelist, outfile) + + def writeUnicodedata(version, table, outfile): # Version print >> outfile, 'version = %r' % version @@ -318,13 +338,9 @@ if version >= "4.1": cjk_end = 0x9FBB - # Character names - print >> outfile, '_charnames = {' - for code in range(len(table)): - if table[code].name: - print >> outfile, '%r: %r,'%(code, table[code].name) - print >> outfile, '''} + write_character_names(outfile, table) + print >> outfile, ''' _code_by_name = dict(map(lambda x:(x[1],x[0]), _charnames.iteritems())) _cjk_prefix = "CJK UNIFIED IDEOGRAPH-" @@ -389,7 +405,7 @@ return _lookup_cjk(name[len(_cjk_prefix):]) if name[:len(_hangul_prefix)] == _hangul_prefix: return _lookup_hangul(name[len(_hangul_prefix):]) - return _code_by_name[name] + return _code_by_name[compression.compress(_codetable, name)] def name(code): if (0x3400 <= code <= 0x4DB5 or @@ -406,7 +422,7 @@ return ("HANGUL SYLLABLE " + _hangul_L[l_code] + _hangul_V[v_code] + _hangul_T[t_code]) - return _charnames[code] + return compression.uncompress(_codelist, _charnames[code]) ''' % (cjk_end, cjk_end) # Categories @@ -547,4 +563,6 @@ print >> outfile, '# This file was generated with the command:' print >> outfile, '# ', ' '.join(sys.argv) print >> outfile + print >> outfile, 'from pypy.module.unicodedata import compression' + print >> outfile writeUnicodedata(unidata_version, table, outfile) Added: pypy/dist/pypy/module/unicodedata/test/test_compression.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/unicodedata/test/test_compression.py Sat Oct 11 13:30:08 2008 @@ -0,0 +1,18 @@ +import py + +from pypy.module.unicodedata import compression + +thisfile = py.magic.autopath() +data = thisfile.read() +lines = data.splitlines() +codetable, codelist = compression.build_compression_table(lines) + +def test_tables_sanity(): + for key, value in codetable.items(): + assert codelist[value] == key + +def test_roundtrip(): + for line in lines: + compressed = compression.compress(codetable, line) + decompressed = compression.uncompress(codelist, compressed) + assert decompressed == line From arigo at codespeak.net Sat Oct 11 13:44:03 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 13:44:03 +0200 (CEST) Subject: [pypy-svn] r58966 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081011114403.C65C216A127@codespeak.net> Author: arigo Date: Sat Oct 11 13:44:03 2008 New Revision: 58966 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_marshal.py Log: (antocuni, arigo) Cancel some changes in test_marshal that look suspicious. The only change left is to call close() on all files. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_marshal.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_marshal.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_marshal.py Sat Oct 11 13:44:03 2008 @@ -7,9 +7,9 @@ import unittest import os -def dump_and_load(obj): +def dump_and_load(obj, *extra_args): f = file(test_support.TESTFN, "wb") - marshal.dump(obj, f) + marshal.dump(obj, f, *extra_args) f.close() f = file(test_support.TESTFN, "rb") got = marshal.load(f) @@ -79,7 +79,7 @@ n /= 123.4567 f = 0.0 - s = marshal.dumps(f) + s = marshal.dumps(f, 2) got = marshal.loads(s) self.assertEqual(f, got) # and with version <= 1 (floats marshalled differently then) @@ -91,11 +91,20 @@ while n < small: for expected in (-n, n): f = float(expected) + s = marshal.dumps(f) got = marshal.loads(s) self.assertEqual(f, got) + + s = marshal.dumps(f, 1) + got = marshal.loads(s) + self.assertEqual(f, got) + got = dump_and_load(f) self.assertEqual(f, got) + + got = dump_and_load(f, 1) + self.assertEqual(f, got) n *= 123.4567 os.unlink(test_support.TESTFN) From arigo at codespeak.net Sat Oct 11 13:51:52 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 13:51:52 +0200 (CEST) Subject: [pypy-svn] r58967 - pypy/branch/2.5-merge/lib-python/modified-2.5.2/test Message-ID: <20081011115152.32E1216A153@codespeak.net> Author: arigo Date: Sat Oct 11 13:51:51 2008 New Revision: 58967 Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_marshal.py Log: (antocuni, arigo) * Make the test slightly less strict. * Add another test about cyclic structures. Modified: pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_marshal.py ============================================================================== --- pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_marshal.py (original) +++ pypy/branch/2.5-merge/lib-python/modified-2.5.2/test/test_marshal.py Sat Oct 11 13:51:51 2008 @@ -238,8 +238,20 @@ self.assertEqual(len(new_head[0]), len(head[0])) self.assertEqual(len(new_head[-1]), len(head[-1])) + # Marshalling objects deeper than MAX_MARSHAL_STACK_DEPTH + # should not crash the interpreter, but can raise ValueError last.append([0]) - self.assertRaises(ValueError, marshal.dumps, head) + try: + marshal.dumps(head) + except ValueError: + pass + + def test_cyclic_objects(self): + # Marshalling cyclic objects should trigger an infinite recursion, + # eventually resulting in a ValueError (or possibly RuntimeError). + cycle = [] + cycle.append(cycle) + self.assertRaises((ValueError, RuntimeError), marshal.dumps, cycle) def test_main(): test_support.run_unittest(IntTestCase, From arigo at codespeak.net Sat Oct 11 14:15:29 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 14:15:29 +0200 (CEST) Subject: [pypy-svn] r58969 - pypy/build/bot2/pypybuildbot Message-ID: <20081011121529.7831A16A138@codespeak.net> Author: arigo Date: Sat Oct 11 14:15:27 2008 New Revision: 58969 Modified: pypy/build/bot2/pypybuildbot/summary.py Log: (pedronis, arigo) Be robust here. Modified: pypy/build/bot2/pypybuildbot/summary.py ============================================================================== --- pypy/build/bot2/pypybuildbot/summary.py (original) +++ pypy/build/bot2/pypybuildbot/summary.py Sat Oct 11 14:15:27 2008 @@ -228,6 +228,8 @@ return rev_anchor def add_section(self, outcome_sets): + if not outcome_sets: + return revs = sorted(outcome_set.revision for outcome_set in outcome_sets) by_rev = sorted((outcome_set.revision, outcome_set) for outcome_set in outcome_sets) From pedronis at codespeak.net Sat Oct 11 14:21:07 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 11 Oct 2008 14:21:07 +0200 (CEST) Subject: [pypy-svn] r58970 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081011122107.B1E3616A1A6@codespeak.net> Author: pedronis Date: Sat Oct 11 14:21:03 2008 New Revision: 58970 Added: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py - copied, changed from r58958, pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Log: quickly hacked a darwin platform (should not really inherit directly from Linux though) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Sat Oct 11 14:21:03 2008 @@ -53,8 +53,12 @@ if sys.platform == 'linux2': from pypy.translator.platform.linux import Linux host = Linux() +elif sys.platform == 'darwin': + from pypy.translator.platform.darwin import Darwin + host = Darwin() else: xxx + platform = host Copied: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py (from r58958, pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py) ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Sat Oct 11 14:21:03 2008 @@ -1,87 +1,13 @@ import py, os -from pypy.translator.platform import Platform, CompilationError, ExecutionResult -from pypy.translator.platform import log -from subprocess import PIPE, Popen +from pypy.translator.platform import linux # xxx -def _run_subprocess(executable, args, env=None): - if isinstance(args, str): - args = str(executable) + ' ' + args - shell = True - else: - if args is None: - args = [str(executable)] - else: - args = [str(executable)] + args - shell = False - pipe = Popen(args, stdout=PIPE, stderr=PIPE, shell=shell, env=env) - stdout, stderr = pipe.communicate() - return pipe.returncode, stdout, stderr - -class Linux(Platform): - link_extra = ['-pthread'] - cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] +class Darwin(linux.Linux): # xxx + link_extra = [] + cflags = ['-O3', '-fomit-frame-pointer'] def __init__(self, cc='gcc'): self.cc = cc - def _compile_args_from_eci(self, eci): - include_dirs = ['-I%s' % (idir,) for idir in eci.include_dirs] - return (self.cflags + list(eci.compile_extra) + include_dirs) - - def _link_args_from_eci(self, eci): - library_dirs = ['-L%s' % (ldir,) for ldir in eci.library_dirs] - libraries = ['-l%s' % (lib,) for lib in eci.libraries] - return (library_dirs + libraries + self.link_extra + - list(eci.link_extra)) - def _args_for_shared(self, args): - return ['-shared'] + args - - def compile(self, cfiles, eci, outputfilename=None, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] - compile_args = self._compile_args_from_eci(eci) - if outputfilename is None: - outputfilename = cfiles[0].purebasename - exe_name = py.path.local(os.path.join(str(cfiles[0].dirpath()), - outputfilename)) - if not standalone: - exe_name += '.so' - ofiles = [] - for cfile in cfiles: - ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) - return self._link(self.cc, ofiles, self._link_args_from_eci(eci), - standalone, exe_name) - - def _compile_c_file(self, cc, cfile, compile_args): - oname = cfile.new(ext='o') - args = ['-c'] + compile_args + [str(cfile), '-o', str(oname)] - self._execute_c_compiler(cc, args, oname) - return oname - - def _execute_c_compiler(self, cc, args, outname): - log.execute(cc + ' ' + ' '.join(args)) - returncode, stdout, stderr = _run_subprocess(cc, args) - if returncode != 0: - errorfile = outname.new(ext='errors') - errorfile.write(stderr) - stderrlines = stderr.splitlines() - for line in stderrlines[:5]: - log.ERROR(line) - if len(stderrlines) > 5: - log.ERROR('...') - raise CompilationError(stdout, stderr) - - def _link(self, cc, ofiles, link_args, standalone, exe_name): - args = [str(ofile) for ofile in ofiles] + link_args - args += ['-o', str(exe_name)] - if not standalone: - args = self._args_for_shared(args) - self._execute_c_compiler(cc, args, exe_name) - return exe_name - - def execute(self, executable, args=None, env=None): - returncode, stdout, stderr = _run_subprocess(str(executable), args, - env) - return ExecutionResult(returncode, stdout, stderr) + return ['-bundle', '-undefined', 'dynamic_lookup'] + args From arigo at codespeak.net Sat Oct 11 14:58:55 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 14:58:55 +0200 (CEST) Subject: [pypy-svn] r58971 - in pypy/branch/getslice/pypy: objspace/flow rpython/test Message-ID: <20081011125855.4AE0016A138@codespeak.net> Author: arigo Date: Sat Oct 11 14:58:54 2008 New Revision: 58971 Modified: pypy/branch/getslice/pypy/objspace/flow/objspace.py pypy/branch/getslice/pypy/rpython/test/test_rlist.py Log: (antocuni, arigo) Don't constant-fold getslice on lists. Modified: pypy/branch/getslice/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/branch/getslice/pypy/objspace/flow/objspace.py (original) +++ pypy/branch/getslice/pypy/objspace/flow/objspace.py Sat Oct 11 14:58:54 2008 @@ -622,6 +622,10 @@ # annotator a lot. if arithmetic and type(result) is long: pass + # don't constant-fold getslice on lists, either + elif name == 'getslice' and type(result) is list: + pass + # otherwise, fine else: try: return self.wrap(result) Modified: pypy/branch/getslice/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/branch/getslice/pypy/rpython/test/test_rlist.py (original) +++ pypy/branch/getslice/pypy/rpython/test/test_rlist.py Sat Oct 11 14:58:54 2008 @@ -324,6 +324,19 @@ assert self.ll_to_list(res.item1) == [6, 7, 8] assert self.ll_to_list(res.item2) == [8, 9] + def test_getslice_not_constant_folded(self): + l = list('abcdef') + + def dummyfn(): + result = [] + for i in range(3): + l2 = l[2:] + result.append(l2.pop()) + return result + + res = self.interpret(dummyfn, []) + assert self.ll_to_list(res) == ['f', 'f', 'f'] + def test_set_del_item(self): def dummyfn(): l = [5, 6, 7] From arigo at codespeak.net Sat Oct 11 15:01:53 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 15:01:53 +0200 (CEST) Subject: [pypy-svn] r58972 - pypy/branch/2.5-merge/pypy/translator/c/gcc/test Message-ID: <20081011130153.0E85F16A1BB@codespeak.net> Author: arigo Date: Sat Oct 11 15:01:52 2008 New Revision: 58972 Modified: pypy/branch/2.5-merge/pypy/translator/c/gcc/test/test_asmgcroot.py Log: (antocuni, arigo) It seems that we found some obscure asmgcc bug :-( Modified: pypy/branch/2.5-merge/pypy/translator/c/gcc/test/test_asmgcroot.py ============================================================================== --- pypy/branch/2.5-merge/pypy/translator/c/gcc/test/test_asmgcroot.py (original) +++ pypy/branch/2.5-merge/pypy/translator/c/gcc/test/test_asmgcroot.py Sat Oct 11 15:01:52 2008 @@ -82,6 +82,32 @@ f.writelines(lines) f.close() + def test_some_unidentified_bug(self): + py.test.skip("XXX FIX ME") + class Element: + pass + elements = [Element() for ii in range(10000)] + l = elements[:] + + def dostuff(): + reverse = {} + for ii in elements: + reverse[ii] = ii + for jj in range(100): + assert len(l) >= 1 + e = l[-1] + del reverse[e] + l.remove(e) + + def f(): + for ii in range(100): + dostuff() + return 0 + + fn = self.getcompiled(f) + res = fn() + assert res == 0 + class TestAsmGCRootWithSemiSpaceGC(AbstractTestAsmGCRoot, test_newgc.TestSemiSpaceGC): From cfbolz at codespeak.net Sat Oct 11 15:26:13 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 11 Oct 2008 15:26:13 +0200 (CEST) Subject: [pypy-svn] r58973 - pypy/dist/pypy/module/unicodedata Message-ID: <20081011132613.C7B3816A13F@codespeak.net> Author: cfbolz Date: Sat Oct 11 15:26:11 2008 New Revision: 58973 Modified: pypy/dist/pypy/module/unicodedata/compression.py Log: (iko, cfbolz): more complex algorithm for generating the compression code table. Modified: pypy/dist/pypy/module/unicodedata/compression.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/compression.py (original) +++ pypy/dist/pypy/module/unicodedata/compression.py Sat Oct 11 15:26:11 2008 @@ -1,34 +1,42 @@ +BITS = 8 def build_compression_table(stringlist): - # build compression code table - BITS = 8 - codes = {} chars = {} - # put all characters into code + # put all used characters for value in stringlist: for char in value: chars.setdefault(char, len(chars)) - # fill code with larger strings - for value in stringlist: - start = 0 - for start in range(len(value)): - for stop in range(start + 1, len(value)): - codes[value[start:stop]] = codes.get(value[start:stop], 0) + 1 - - # take most common strings - s = [(freq, code) for (code, freq) in codes.iteritems() if len(code) > 1] - s.sort() - s.reverse() - common = chars.keys() + [code for freq, code in s[:2 ** BITS - len(chars)]] - assert len(common) <= 2 ** BITS - - finalcodes = {} - for code in common: - assert code not in finalcodes - finalcodes[code] = len(finalcodes) - return finalcodes, common + finalcodes = chars.keys() + stringlist = [s for s in stringlist if len(s) > 1] + # fill code with larger strings + while len(finalcodes) < 2 ** BITS and stringlist: + codes = {} + for string in stringlist: + for stop in range(1, len(string)): + codes[string[:stop]] = codes.get(string[:stop], 0) + 1 + + s = [(freq * (len(code) - 1), code) for (code, freq) in codes.iteritems()] + s.sort() + newcode = s[-1][1] + print repr(newcode) + newstringlist = [] + for string in stringlist: + if string.startswith(newcode): + newstring = string[len(newcode):] + if len(newstring) > 1: + newstringlist.append(newstring) + else: + newstringlist.append(string) + assert newstringlist != stringlist + stringlist = newstringlist + finalcodes.append(newcode) + + codetable = {} + for code in finalcodes: + codetable[code] = len(codetable) + return codetable, finalcodes def compress(codetable, s): start = 0 From xoraxax at codespeak.net Sat Oct 11 15:43:03 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 11 Oct 2008 15:43:03 +0200 (CEST) Subject: [pypy-svn] r58974 - in pypy/build/benchmem: . testing Message-ID: <20081011134303.0B47316A169@codespeak.net> Author: xoraxax Date: Sat Oct 11 15:43:02 2008 New Revision: 58974 Modified: pypy/build/benchmem/report.py pypy/build/benchmem/runbench.py pypy/build/benchmem/smaps.py pypy/build/benchmem/testing/test_benchtool.py Log: (hpk, xoraxax) Add resultset filtering, new basesize reporting, new tests. Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Sat Oct 11 15:43:02 2008 @@ -47,13 +47,13 @@ class TableReporter: def __init__(self, resultset): - self.resultset = resultset + self.resultset = resultset.filter(benchtype="objsizes") begin = report = end = lambda x: None # hooks def run(self): self.begin() - for name, results in resultset.getname2results(): + for name, results in self.resultset.getname2results(): row0 = ["num"] + [result.executable for result in results] numsnapshots = min([len(i.snapshots) for i in results]) @@ -109,7 +109,7 @@ class IncrementalSizePerBench: def __init__(self, resultset): - self.resultset = resultset.filter(benchtype="sizes") + self.resultset = resultset.filter(benchtype="objsizes") def getexecutables(self): ret = None @@ -123,6 +123,8 @@ return ret def run(self): + if not self.resultset: + return tw = py.io.TerminalWriter() tw.sep("=", "Incremental private RSS of size benchmarks") @@ -156,18 +158,42 @@ def __init__(self, resultset): self.resultset = resultset.filter(benchtype="basesize") + def getexecutables(self): + return [r.executable for r in self.resultset.results] + def run(self): - XXX tw = py.io.TerminalWriter() - tw.sep("=", "Base Size of interpreters (using sizes.bench_list_of_None)") - sorter = Sorter(self.reader.name2results).filter(benchprefix="bench_list_of_None") - row0 = "executable rss shared_clean shared_dirty private_clean private_dirty".split() + tw.sep("=", "Basesize of interpreters") + executables = self.getexecutables() + row0 = ['Group-Pagestate'] + executables rows = [row0] - for result in sorter.name2results['sizes.bench_list_of_None']: - row = [result.executable] - for name in row0[1:]: - row.append(getattr(result.snapshots[0], name)) + row_kinds = "shared_clean shared_dirty private_clean private_dirty".split() + results = self.resultset.results + def makerow(rowname, mapping_func): + row = [rowname] + for result in results: + row.append(mapping_func(result)) rows.append(row) + HEAP = runbench.Mappings.HEAP + CODE = runbench.Mappings.CODE + DATA = runbench.Mappings.DATA + makerow("HEAP-RSS", lambda result: + result.snapshot.filter(group=HEAP).rss) + makerow("HEAP-private_clean", lambda result: + result.snapshot.filter(group=HEAP).private_clean) + makerow("HEAP-private_dirty", lambda result: + result.snapshot.filter(group=HEAP).private_dirty) + makerow("IP-CODE-shared_clean", lambda result: + result.snapshot.filter(group=result.executable, kind=CODE).shared_clean) + makerow("IP-CODE-private_clean", lambda result: + result.snapshot.filter(group=result.executable, kind=CODE).private_clean) + makerow("IP-DATA-RSS", lambda result: + result.snapshot.filter(group=result.executable, kind=DATA).rss) + makerow("IP-DATA-private_clean", lambda result: + result.snapshot.filter(group=result.executable, kind=DATA).private_clean) + makerow("IP-DATA-private_dirty", lambda result: + result.snapshot.filter(group=result.executable, kind=DATA).private_dirty) +#rest tw.line(asciitable(rows)) if __name__ == "__main__": @@ -180,7 +206,7 @@ #maxtable_overview(reader) CheckpointDetails(resultset).run() IncrementalSizePerBench(resultset).run() - #BaseSizeOfInterpreters(resultset).run() + BaseSizeOfInterpreters(resultset).run() if options.gnuplot: Gnuplot(resultset).run() Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Sat Oct 11 15:43:02 2008 @@ -56,9 +56,9 @@ class BenchRunnerObjsize(BenchRunner): - def __init__(self, executable, fsname, logpath, options): + def __init__(self, executable, logpath, options): self.executable = executable - self.benchpath = benchmarkdir.join(fsname) + self.benchpath = benchmarkdir.join("sizes.py") assert self.benchpath.check() self.logpath = py.path.local(logpath) self.logstream = self.logpath.open("a") @@ -95,7 +95,7 @@ def write_benchheader(self, benchname, args): print >>self.logstream, self.SEPBENCH - print >>self.logstream, "#benchtype=sizes" + print >>self.logstream, "#benchtype=objsizes" print >>self.logstream, "#executable=%s" %(str(self.executable ),) print >>self.logstream, "#benchpath=%s" %(self.benchpath.basename,) print >>self.logstream, "#benchname=%s" %(benchname,) @@ -151,6 +151,9 @@ results = [] self.results = results + def __nonzero__(self): + return bool(self.results) + def getname2results(self): name2results = {} for result in self.results: @@ -223,7 +226,7 @@ class ObjsizeResult(Result): - benchtype = "sizes" + benchtype = "objsizes" def __init__(self, snapshots, executable, benchpath, benchname, benchargs): assert snapshots self.snapshots = snapshots @@ -254,25 +257,48 @@ self.executable = executable -class Snapshot(object): +class Mappings(object): + HEAP, CODE, DATA = object(), object(), object() + def __init__(self, mappings): - assert mappings self.mappings = mappings for name in smaps.Mapping._attrnames: setattr(self, name, sum([getattr(x, name) for x in mappings])) self.private = self.private_dirty + self.private_clean self.shared = self.shared_dirty + self.shared_clean - def heap_private(self): - private = 0 + def filter(self, group=None, kind=None, inv=False): + new_mappings = [] for mapping in self.mappings: - if mapping.filename == "[heap]" or not mapping.filename: - private += mapping.private_clean + mapping.private_dirty - return private + matches = True + if group is not None: + if group is self.HEAP: + if not (mapping.filename == "[heap]" + or not mapping.filename): + matches = False + elif not mapping.filename.endswith(group): + matches = False + if kind is not None: + if kind is self.CODE and mapping.mode != 'r-xp': + matches = False + if kind is self.DATA and mapping.mode != 'rw-p': + matches = False + + if matches != bool(inv): + new_mappings.append(mapping) + return Mappings(new_mappings) def memusage(self): return "private: %d, shared: %d" %(self.private, self.shared) +class Snapshot(Mappings): + def __init__(self, mappings): + assert mappings + Mappings.__init__(self, mappings) + + def heap_private(self): + return self.filter(group=self.HEAP).private + # # ============================================================================== # Option Handling @@ -309,19 +335,21 @@ l.append(executable) return l -def getrunnerclass(fsname): - if fsname == "sizes.py": +def getrunnerclass(benchtype): + if benchtype == "objsizes": return BenchRunnerObjsize + if benchtype == "basesize": + return BenchRunnerBaseSize if __name__ == '__main__': (options, args) = parser.parse_args() benchlog = getbenchlog(options) if not args: - args = ("sizes.py",) + args = ("objsizes", "basesize") for executable in getexecutables(options): - for fsname in args: - Runner = getrunnerclass(fsname) - runner = Runner(executable, fsname, benchlog, options) + for benchtype in args: + Runner = getrunnerclass(benchtype) + runner = Runner(executable, benchlog, options) runner.run() print "bench results append to -->>>", benchlog Modified: pypy/build/benchmem/smaps.py ============================================================================== --- pypy/build/benchmem/smaps.py (original) +++ pypy/build/benchmem/smaps.py Sat Oct 11 15:43:02 2008 @@ -62,4 +62,8 @@ for name, value in zip(self._headattrnames, parts): setattr(self, name, value) self.inode = int(self.inode) - + + def __repr__(self): + attrdata = ",".join([str(getattr(self, name)) for name in self._attrnames]) + headcols = " ".join([str(getattr(self, name)) for name in self._headattrnames]) + return "" % (attrdata, headcols) Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Sat Oct 11 15:43:02 2008 @@ -3,6 +3,7 @@ import runbench import smaps +import report def setup_module(mod): if sys.platform.find("linux") == -1: @@ -27,7 +28,7 @@ benchlog=tmpdir.join("log") class options: numiter = 10 - runner = runbench.BenchRunnerObjsize("python2.5", "sizes.py", benchlog, options) + runner = runbench.BenchRunnerObjsize("python2.5", benchlog, options) assert runner.benchpath.basename == "sizes.py" runner.run() resultset = runbench.ResultSet() @@ -43,11 +44,11 @@ script = py.path.local(runbench.__file__).dirpath("runbench.py") output = py.process.cmdexec("python %s --numiter=10" %(script)) -def test_report_functional(): +def test_report_objsizes_functional(): tmpdir = py.test.ensuretemp("test_report_functional") script = py.path.local(runbench.__file__).dirpath("runbench.py") benchlog = tmpdir.join("benchlog") - py.process.cmdexec("%s --benchlog=%s --numiter=10" %(script, benchlog)) + py.process.cmdexec("%s --benchlog=%s --numiter=10 objsizes" %(script, benchlog)) report = script.dirpath("report.py") old = tmpdir.chdir() try: @@ -158,6 +159,31 @@ val2 = getattr(snap.mappings[1], name) assert sumval == val1 + val2 +def test_mapping_grouping(): + lines = [ + "988,796,0,0,796,0 08048000-0813f000 r-xp 00000000 fd:00 75457 /tmp/IP", + "420,96,0,0,4,92 08048000-0813f000 rw-p 00000000 fd:00 75457 /tmp/IP", + "420,0,0,0,0,13 08048000-0813f000 rw-p 00000000 fd:00 75457 /usr/foo.lib", + "504,416,0,0,0,416 08165000-081e3000 rw-p 08165000 00:00 0 [heap]", + "524,400,0,0,0,400 b7d0e000-b7d91000 rw-p b7d0e000 00:00 0", + ] + snap = runbench.Snapshot([smaps.Mapping(line) for line in lines]) + m_heap = snap.filter(group=snap.HEAP) + assert m_heap.private == 416 + 400 + assert len(m_heap.mappings) == 2 + + m_noheap = snap.filter(group=snap.HEAP, inv=True) + assert len(m_noheap.mappings) == 3 + + m_noip_noheap = m_noheap.filter(group="IP", inv=True) + assert len(m_noip_noheap.mappings) == 1 + + m_ip_code = snap.filter(group="IP", kind=snap.CODE) + assert m_ip_code.private_clean == 796 + assert m_ip_code.private_dirty == 0 + m_ip_data = snap.filter(group="IP", kind=snap.DATA) + assert m_ip_data.private_clean == 4 + assert m_ip_data.private_dirty == 92 def test_basesize(): tmpdir = py.test.ensuretemp("basesize") @@ -173,3 +199,36 @@ assert result.benchtype == 'basesize' assert result.executable.endswith('python2.5') assert result.snapshot.heap_private() > 42 + +def test_basesize_reporting(): + tmpdir = py.test.ensuretemp("test_basesize_reporting") + script = py.path.local(runbench.__file__).dirpath("runbench.py") + benchlog = tmpdir.join("benchlog") + print "Runner" + py.process.cmdexec("%s --benchlog=%s basesize" % (script, benchlog)) + report = script.dirpath("report.py") + old = tmpdir.chdir() + try: + print "Reporter" + out = py.process.cmdexec("%s --benchlog %s" %(report, benchlog,)) + assert out.lower().find("basesize") != -1 + finally: + old.chdir() + +def test_basesize_multiple_binaries_half_functional(): + tmpdir = py.test.ensuretemp("test_basesize_hf") + script = py.path.local(runbench.__file__).dirpath("runbench.py") + benchlog = tmpdir.join("benchlog") + py.process.cmdexec("%s -e python2.5,python2.5 --benchlog=%s basesize" % (script, benchlog)) + + resultset = runbench.ResultSet() + resultset.parse(benchlog) + + assert len(resultset.results) == 2 + result1, result2 = resultset.results + assert result1.benchtype == 'basesize' + assert result1.executable.endswith('python2.5') + assert result1.snapshot.heap_private() > 42 + assert result2.snapshot.heap_private() - result1.snapshot.heap_private() < 21 + report.CheckpointDetails(resultset).run() # shouldnt do anything + From fijal at codespeak.net Sat Oct 11 15:43:08 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 11 Oct 2008 15:43:08 +0200 (CEST) Subject: [pypy-svn] r58975 - in pypy/branch/cbuild-refactor/pypy: config translator/c translator/platform translator/platform/test Message-ID: <20081011134308.2931616A1A6@codespeak.net> Author: fijal Date: Sat Oct 11 15:43:07 2008 New Revision: 58975 Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py (contents, props changed) Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Log: (fijal, pedronis) (in-progress) nice makefile creation Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/config/translationoption.py (original) +++ pypy/branch/cbuild-refactor/pypy/config/translationoption.py Sat Oct 11 15:43:07 2008 @@ -352,6 +352,10 @@ 'maemo', ] +def set_platform(translateconfig, config): + from pypy.translator.platform import set_platform + set_platform(translateconfig.platform, config.translation.cc) + def get_platform(config): from pypy.translator.platform import host return host Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Sat Oct 11 15:43:07 2008 @@ -44,6 +44,8 @@ class CCompilerDriver(object): def __init__(self, platform, cfiles, eci, outputfilename=None, profbased=False): + # XXX config might contain additional link and compile options. + # We need to fish for it somehow. self.platform = platform self.cfiles = cfiles self.eci = eci @@ -164,6 +166,19 @@ DEBUG_DEFINES = {'RPY_ASSERT': 1, 'RPY_LL_ASSERT': 1} + def generate_graphs_for_llinterp(self, db=None): + # prepare the graphs as when the source is generated, but without + # actually generating the source. + if db is None: + db = self.build_database() + graphs = db.all_graphs() + db.gctransformer.prepare_inline_helpers(graphs) + for node in db.containerlist: + if isinstance(node, FuncNode): + for funcgen in node.funcgens: + funcgen.patch_graph(copy_graph=False) + return db + def generate_source(self, db=None, defines={}): assert self.c_source_filename is None translator = self.translator @@ -204,20 +219,110 @@ if self.standalone: self.gen_makefile(targetdir) return cfile + + def gen_makefile(self, targetdir): + def write_list(lst, prefix): + for i, fn in enumerate(lst): + print >> f, prefix, fn, + if i < len(lst)-1: + print >> f, '\\' + else: + print >> f + prefix = ' ' * len(prefix) - def generate_graphs_for_llinterp(self, db=None): - # prepare the graphs as when the source is generated, but without - # actually generating the source. - if db is None: - db = self.build_database() - graphs = db.all_graphs() - db.gctransformer.prepare_inline_helpers(graphs) - for node in db.containerlist: - if isinstance(node, FuncNode): - for funcgen in node.funcgens: - funcgen.patch_graph(copy_graph=False) - return db + self.eci = self.eci.merge(ExternalCompilationInfo( + includes=['.', str(self.targetdir)])) + compiler = self.getccompiler() + + #self.adaptflags(compiler) + assert self.config.translation.gcrootfinder != "llvmgc" + cfiles = [] + ofiles = [] + gcmapfiles = [] + for fn in compiler.cfilenames: + fn = py.path.local(fn) + if fn.dirpath() == targetdir: + name = fn.basename + else: + assert fn.dirpath().dirpath() == udir + name = '../' + fn.relto(udir) + + name = name.replace("\\", "/") + cfiles.append(name) + if self.config.translation.gcrootfinder == "asmgcc": + ofiles.append(name[:-2] + '.s') + gcmapfiles.append(name[:-2] + '.gcmap') + else: + ofiles.append(name[:-2] + '.o') + + if self.config.translation.cc: + cc = self.config.translation.cc + else: + cc = self.eci.platform.get_compiler() + if cc is None: + cc = 'gcc' + make_no_prof = '' + if self.has_profopt(): + profopt = self.config.translation.profopt + default_target = 'profopt' + # XXX horrible workaround for a bug of profiling in gcc on + # OS X with functions containing a direct call to fork() + non_profilable = [] + assert len(compiler.cfilenames) == len(ofiles) + for fn, oname in zip(compiler.cfilenames, ofiles): + fn = py.path.local(fn) + if '/*--no-profiling-for-this-file!--*/' in fn.read(): + non_profilable.append(oname) + if non_profilable: + make_no_prof = '$(MAKE) %s' % (' '.join(non_profilable),) + else: + profopt = '' + default_target = '$(TARGET)' + f = targetdir.join('Makefile').open('w') + print >> f, '# automatically generated Makefile' + print >> f + print >> f, 'PYPYDIR =', autopath.pypydir + print >> f + print >> f, 'TARGET =', py.path.local(compiler.outputfilename).basename + print >> f + print >> f, 'DEFAULT_TARGET =', default_target + print >> f + write_list(cfiles, 'SOURCES =') + print >> f + if self.config.translation.gcrootfinder == "asmgcc": + write_list(ofiles, 'ASMFILES =') + write_list(gcmapfiles, 'GCMAPFILES =') + print >> f, 'OBJECTS = $(ASMFILES) gcmaptable.s' + else: + print >> f, 'GCMAPFILES =' + write_list(ofiles, 'OBJECTS =') + print >> f + def makerel(path): + rel = py.path.local(path).relto(py.path.local(autopath.pypydir)) + if rel: + return os.path.join('$(PYPYDIR)', rel) + else: + return path + args = ['-l'+libname for libname in self.eci.libraries] + print >> f, 'LIBS =', ' '.join(args) + args = ['-L'+makerel(path) for path in self.eci.library_dirs] + print >> f, 'LIBDIRS =', ' '.join(args) + args = ['-I'+makerel(path) for path in self.eci.include_dirs] + write_list(args, 'INCLUDEDIRS =') + print >> f + print >> f, 'CFLAGS =', ' '.join(compiler.compile_extra) + print >> f, 'LDFLAGS =', ' '.join(compiler.link_extra) + if self.config.translation.thread: + print >> f, 'TFLAGS = ' + '-pthread' + else: + print >> f, 'TFLAGS = ' + '' + print >> f, 'PROFOPT = ' + profopt + print >> f, 'MAKENOPROF = ' + make_no_prof + print >> f, 'CC = ' + cc + print >> f + print >> f, MAKEFILE.strip() + f.close() class ModuleWithCleanup(object): def __init__(self, mod): @@ -414,7 +519,6 @@ compiler.link_extra.append(self.config.translation.linkerflags) def gen_makefile(self, targetdir): - return # XXX def write_list(lst, prefix): for i, fn in enumerate(lst): print >> f, prefix, fn, Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Sat Oct 11 15:43:07 2008 @@ -33,6 +33,9 @@ def execute(self, file_to_exec, args=None, env=None): raise NotImplementedError("Pure abstract baseclass") + def gen_makefile(self, cfiles, eci, exe_name=None, path=None): + raise NotImplementedError("Pure abstract baseclass") + def __repr__(self): return '<%s cc=%s>' % (self.__class__.__name__, self.cc) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sat Oct 11 15:43:07 2008 @@ -3,6 +3,7 @@ from pypy.translator.platform import Platform, CompilationError, ExecutionResult from pypy.translator.platform import log from subprocess import PIPE, Popen +from pypy.tool import autopath def _run_subprocess(executable, args, env=None): if isinstance(args, str): @@ -18,6 +19,67 @@ stdout, stderr = pipe.communicate() return pipe.returncode, stdout, stderr +class Definition(object): + def __init__(self, name, value): + self.name = name + self.value = value + + def write(self, f): + def write_list(prefix, lst): + for i, fn in enumerate(lst): + print >> f, prefix, fn, + if i < len(lst)-1: + print >> f, '\\' + else: + print >> f + prefix = ' ' * len(prefix) + name, value = self.name, self.value + if isinstance(value, str): + f.write('%s = %s\n' % (name, value)) + else: + write_list('%s =' % (name,), value) + +class Rule(object): + def __init__(self, target, deps, body): + self.target = target + self.deps = deps + self.body = body + + def write(self, f): + target, deps, body = self.target, self.deps, self.body + dep_s = ' '.join(deps) + f.write('%s: %s\n' % (target, dep_s)) + if isinstance(body, str): + f.write('\t%s\n' % body) + else: + f.write('\t%s\n' % '\n\t'.join(body)) + f.write('\n') + +class Comment(object): + def __init__(self, body): + self.body = body + + def write(self, f): + f.write('# %s\n' % (self.body,)) + +class GnuMakefile(object): + def __init__(self): + self.lines = [] + + def definition(self, name, value): + self.lines.append(Definition(name, value)) + + def rule(self, target, deps, body): + self.lines.append(Rule(target, deps, body)) + + def comment(self, body): + self.lines.append(Comment(body)) + + def write(self, f): + for line in self.lines: + line.write(f) + f.flush() + class Linux(Platform): link_extra = ['-pthread'] cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] @@ -85,3 +147,22 @@ returncode, stdout, stderr = _run_subprocess(str(executable), args, env) return ExecutionResult(returncode, stdout, stderr) + + def gen_makefile(self, cfiles, eci, exe_name=None, path=None): + m = GnuMakefile() + # XXX cfiles relative to path + m.comment('automatically generated makefile') + definitions = [ + ('PYPYDIR', str(autopath.pypy_dir)), + ('TARGET', exe_name.basename), + ('DEFAULT_TARGET', '$(TARGET)'), + ('SOURCES', whacked_cfiles), + ('OBJECTS', whacked_ofiles), + ('LIBS', whacked_libs), + ] + for args in definitions: + m.definition(*args) + # + #for includedir in eci.include_dirs: + # if includedir.relto + # Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py Sat Oct 11 15:43:07 2008 @@ -0,0 +1,21 @@ + +from pypy.translator.platform.linux import GnuMakefile as Makefile +from StringIO import StringIO +import re + +def test_simple_makefile(): + m = Makefile() + m.definition('CC', 'xxx') + m.definition('XX', ['a', 'b', 'c']) + m.rule('x', 'y', 'do_stuff') + m.rule('y', 'z', ['a', 'b', 'ced']) + s = StringIO() + m.write(s) + val = s.getvalue() + expected_lines = [ + r'CC += +xxx', + r'XX += +a \\\n +b \\\n +c', + r'^x: y\n\tdo_stuff', + r'^y: z\n\ta\n\tb\n\tced\n'] + for i in expected_lines: + assert re.search(i, val, re.M) From hpk at codespeak.net Sat Oct 11 15:44:17 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 11 Oct 2008 15:44:17 +0200 (CEST) Subject: [pypy-svn] r58976 - in pypy/build/benchmem: . benchmark Message-ID: <20081011134417.75FDC16A169@codespeak.net> Author: hpk Date: Sat Oct 11 15:44:17 2008 New Revision: 58976 Modified: pypy/build/benchmem/benchmark/sizes.py pypy/build/benchmem/report.py Log: (xoraxax,hpk) dont depend on socket module, add benchmarks Modified: pypy/build/benchmem/benchmark/sizes.py ============================================================================== --- pypy/build/benchmem/benchmark/sizes.py (original) +++ pypy/build/benchmem/benchmark/sizes.py Sat Oct 11 15:44:17 2008 @@ -115,6 +115,20 @@ l = [{i:None} for i in range(iter1)] checkpoint(collect=True) +def bench_list_of_dict_oldinstance_withintattr(iter1): + class A: + def __init__(self, i): + self.i = i + l = [{A(i):None} for i in range(iter1)] + checkpoint(collect=True) + +def bench_list_of_dict_newinstance_withintattr(iter1): + class A(object): + def __init__(self, i): + self.i = i + l = [{A(i):None} for i in range(iter1)] + checkpoint(collect=True) + def bench_list_of_dict_strkey_len1(iter1): l = [{'%07d'%i:None} for i in range(iter1)] checkpoint(collect=True) @@ -360,6 +374,8 @@ # ____________________________________________________________ +import sys,new +sys.modules['socket'] = new.module("socket") from email.Message import Message def bench_list_of_messages(iter1): Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Sat Oct 11 15:44:17 2008 @@ -140,9 +140,9 @@ for result in results: incsize = self.get_incremental_size(result) # colors work but messup table layout - #color = incsize <= basesize and "green" or "red" - #row.append(tw.markup(str(incsize), **{color:True})) - row.append(incsize) + color = incsize <= basesize and "green" or "red" + row.append(tw.markup(str(incsize), **{color:True})) + #row.append(incsize) rows.append(row) tw.line(asciitable(rows)) From antocuni at codespeak.net Sat Oct 11 15:49:54 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 11 Oct 2008 15:49:54 +0200 (CEST) Subject: [pypy-svn] r58977 - in pypy/branch/2.5-merge/pypy/interpreter: pyparser test Message-ID: <20081011134954.3993216A1A6@codespeak.net> Author: antocuni Date: Sat Oct 11 15:49:53 2008 New Revision: 58977 Modified: pypy/branch/2.5-merge/pypy/interpreter/pyparser/astbuilder.py pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py Log: (antocuni, arigo) fix some non-sense in the parser Modified: pypy/branch/2.5-merge/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/pyparser/astbuilder.py Sat Oct 11 15:49:53 2008 @@ -760,6 +760,9 @@ else: token = atoms[2] assert isinstance(token, TokenObject) + assert token.name == builder.parser.tokens['NAME'] + if token.get_value() != 'as': + raise SyntaxError("invalid syntax", token.lineno, token.col) varexpr = atoms[3] var = to_lvalue(varexpr, consts.OP_ASSIGN) body = atoms[5] @@ -791,11 +794,15 @@ if index < l: token = atoms[index] assert isinstance(token, TokenObject) - if token.get_value() == 'as': - token = atoms[index+1] - assert isinstance(token, TokenObject) - as_name = token.get_value() - index += 2 + if token.name == builder.parser.tokens['NAME']: + if token.get_value() == 'as': + token = atoms[index+1] + assert isinstance(token, TokenObject) + as_name = token.get_value() + index += 2 + else: + raise SyntaxError("invalid syntax", token.lineno, token.col) + names.append((name, as_name)) # move forward until next ',' # XXX: what is it supposed to do ? @@ -867,11 +874,14 @@ if index < l: token = tokens[index] assert isinstance(token, TokenObject) - if token.get_value() == 'as': - token = tokens[index+1] - assert isinstance(token, TokenObject) - as_name = token.get_value() - index += 2 + if token.name == builder.parser.tokens['NAME']: + if token.get_value() == 'as': + token = tokens[index+1] + assert isinstance(token, TokenObject) + as_name = token.get_value() + index += 2 + else: + raise SyntaxError("invalid syntax", token.lineno, token.col) names.append((name, as_name)) if index < l: # case ',' index += 1 Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py Sat Oct 11 15:49:53 2008 @@ -537,6 +537,22 @@ exec "from __future__ import with_statement\nimport sys as foo" + def test_missing_as_SyntaxError(self): + snippets = [ + "import os.path a bar ", + "from os import path a bar", + """from __future__ import with_statement +with foo a bar: + pass +"""] + for snippet in snippets: + try: + exec snippet + except SyntaxError: + pass + else: + assert False, "%s: did not raise SyntaxError" % snippet + def test_with_propagate_compileflag(self): s = """from __future__ import with_statement From hpk at codespeak.net Sat Oct 11 16:00:24 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 11 Oct 2008 16:00:24 +0200 (CEST) Subject: [pypy-svn] r58978 - pypy/build/benchmem Message-ID: <20081011140024.B240816A1CB@codespeak.net> Author: hpk Date: Sat Oct 11 16:00:23 2008 New Revision: 58978 Modified: pypy/build/benchmem/report.py Log: (xoraxax,hpk) fix python2.5 maemo reporting to include libpython2.5, add reporting about "REST", i.e. non-HEAP non -interpreter mappings Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Sat Oct 11 16:00:23 2008 @@ -193,7 +193,15 @@ result.snapshot.filter(group=result.executable, kind=DATA).private_clean) makerow("IP-DATA-private_dirty", lambda result: result.snapshot.filter(group=result.executable, kind=DATA).private_dirty) -#rest + makerow("REST-private_clean", lambda result: + result.snapshot.filter(group=result.executable, inv=True). + filter(group=HEAP, inv=True).private_clean) + makerow("REST-private_dirty", lambda result: + result.snapshot.filter(group=result.executable, inv=True). + filter(group=HEAP, inv=True).private_dirty) + makerow("REST-RSS", lambda result: + result.snapshot.filter(group=result.executable, inv=True). + filter(group=HEAP, inv=True).rss) tw.line(asciitable(rows)) if __name__ == "__main__": From antocuni at codespeak.net Sat Oct 11 16:03:53 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 11 Oct 2008 16:03:53 +0200 (CEST) Subject: [pypy-svn] r58979 - in pypy/branch/2.5-merge/pypy/interpreter: pyparser test Message-ID: <20081011140353.E2BC016A1D0@codespeak.net> Author: antocuni Date: Sat Oct 11 16:03:53 2008 New Revision: 58979 Modified: pypy/branch/2.5-merge/pypy/interpreter/pyparser/future.py pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py Log: (antocuni, arigo) argh! If the file starts with *exactly* a newline, the __future__ imports were not enabled Modified: pypy/branch/2.5-merge/pypy/interpreter/pyparser/future.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/pyparser/future.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/pyparser/future.py Sat Oct 11 16:03:53 2008 @@ -39,6 +39,7 @@ pass whitespace = ' \t\f' +whitespace_or_newline = whitespace + '\n\r' letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxyz_' alphanumerics = letters + '1234567890' @@ -79,7 +80,7 @@ c = self.getc() if c in ["'", '"'] and not self.docstringConsumed: self.consumeDocstring() - elif c in whitespace: + elif c in whitespace_or_newline: self.consumeEmptyLine() elif c == '#': self.consumeComment() Modified: pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py (original) +++ pypy/branch/2.5-merge/pypy/interpreter/test/test_syntax.py Sat Oct 11 16:03:53 2008 @@ -305,6 +305,27 @@ assert acontext.calls == '__enter__ __exit__'.split() + def test_start_with_blank_line(self): + s = """ +from __future__ import with_statement +if 1: + class Context: + def __init__(self): + self.calls = list() + + def __enter__(self): + self.calls.append('__enter__') + + def __exit__(self, exc_type, exc_value, exc_tb): + self.calls.append('__exit__') + + acontext = Context() + with acontext: + pass +""" + exec s + assert acontext.calls == '__enter__ __exit__'.split() + def test_with_as_var(self): s = """from __future__ import with_statement From pedronis at codespeak.net Sat Oct 11 16:20:49 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 11 Oct 2008 16:20:49 +0200 (CEST) Subject: [pypy-svn] r58980 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081011142049.7651E16A202@codespeak.net> Author: pedronis Date: Sat Oct 11 16:20:47 2008 New Revision: 58980 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Log: (fijal, pedronis) more makefile generation Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Sat Oct 11 16:20:47 2008 @@ -3,8 +3,9 @@ from pypy.translator.platform import linux # xxx class Darwin(linux.Linux): # xxx - link_extra = [] + link_flags = [] cflags = ['-O3', '-fomit-frame-pointer'] + # -mdynamic-no-pic for standalone def __init__(self, cc='gcc'): self.cc = cc Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sat Oct 11 16:20:47 2008 @@ -81,20 +81,29 @@ f.flush() class Linux(Platform): - link_extra = ['-pthread'] + link_flags = ['-pthread'] cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] def __init__(self, cc='gcc'): self.cc = cc + def _libs(self, libraries): + return ['-l%s' % (lib,) for lib in libraries] + + def _libdirs(self, library_dirs): + return ['-L%s' % (ldir,) for ldir in library_dirs] + + def _includedirs(self, include_dirs): + return ['-I%s' % (idir,) for idir in include_dirs] + def _compile_args_from_eci(self, eci): - include_dirs = ['-I%s' % (idir,) for idir in eci.include_dirs] + include_dirs = self._includedirs(eci.include_dirs) return (self.cflags + list(eci.compile_extra) + include_dirs) def _link_args_from_eci(self, eci): - library_dirs = ['-L%s' % (ldir,) for ldir in eci.library_dirs] - libraries = ['-l%s' % (lib,) for lib in eci.libraries] - return (library_dirs + libraries + self.link_extra + + library_dirs = self._libdirs(eci.library_dirs) + libraries = self._libs(eci.libraries) + return (library_dirs + libraries + self.link_flags + list(eci.link_extra)) def _args_for_shared(self, args): @@ -149,20 +158,51 @@ return ExecutionResult(returncode, stdout, stderr) def gen_makefile(self, cfiles, eci, exe_name=None, path=None): + cfiles = [py.path.local(f) for f in cfiles] + cfiles += [py.path.local(f) for f in eci.separate_module_files] + + if path is None: + path = cfiles[0].dirpath() + else: + path = py.path.local(path) + + pypypath = py.path.local(autopath.pypydir) + + def pathrel(fpath): + if fpath.dirpath() == path: + return fpath.basename + elif fpath.dirpath().dirpath() == path.dirpath(): + return '../' + fpath.relto(path.dirpath()) + else: + return str(fpath) + + def pypyrel(fpath): + rel = py.path.local(fpath).relto(pypypath) + if rel: + return os.path.join('$(PYPYDIR)', rel) + else: + return fpath + + rel_cfiles = [pathrel(cfile) for cfile in cfiles] + rel_ofiles = [rel_cfile[:-2]+'.o' for rel_cfile in rel_cfiles] + + rel_includedirs = [pypyrel(incldir) for incldir in eci.include_dirs] + m = GnuMakefile() - # XXX cfiles relative to path m.comment('automatically generated makefile') definitions = [ ('PYPYDIR', str(autopath.pypy_dir)), ('TARGET', exe_name.basename), ('DEFAULT_TARGET', '$(TARGET)'), - ('SOURCES', whacked_cfiles), - ('OBJECTS', whacked_ofiles), - ('LIBS', whacked_libs), + ('SOURCES', rel_cfiles), + ('OBJECTS', rel_ofiles), + ('LIBS', self._libs(eci.libraries)), + ('LIBDIRS', self._libdirs(eci.library_dirs)), + ('INCLUDEDIRS', self._includedirs(rel_includedirs)), + ('CFLAGS', self.cflags + list(eci.compile_extra)), + ('LDFLAGS', self.link_flags + list(eci.link_extra)), + ('CC', self.cc) ] for args in definitions: m.definition(*args) - # - #for includedir in eci.include_dirs: - # if includedir.relto - # + From hpk at codespeak.net Sat Oct 11 16:26:18 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 11 Oct 2008 16:26:18 +0200 (CEST) Subject: [pypy-svn] r58981 - pypy/build/benchmem Message-ID: <20081011142618.7821D16A232@codespeak.net> Author: hpk Date: Sat Oct 11 16:26:17 2008 New Revision: 58981 Modified: pypy/build/benchmem/runbench.py Log: (xoraxax,hpk) also account for lib-python2.5 (on maemo cpython loads mostly as a lib) Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Sat Oct 11 16:26:17 2008 @@ -276,7 +276,7 @@ if not (mapping.filename == "[heap]" or not mapping.filename): matches = False - elif not mapping.filename.endswith(group): + elif not group in mapping.filename: matches = False if kind is not None: if kind is self.CODE and mapping.mode != 'r-xp': From arigo at codespeak.net Sat Oct 11 16:27:11 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 16:27:11 +0200 (CEST) Subject: [pypy-svn] r58982 - in pypy: branch/2.5-merge trunk Message-ID: <20081011142711.F0498168506@codespeak.net> Author: arigo Date: Sat Oct 11 16:27:11 2008 New Revision: 58982 Added: pypy/trunk/ - copied from r58980, pypy/branch/2.5-merge/ Removed: pypy/branch/2.5-merge/ Log: (fijal, arigo) Teh 2.5-merge branch is in good shape, and we have been using it as teh trunk for teh whole sprint, mostly. So let's use this as a good excuse to call it "trunk". From arigo at codespeak.net Sat Oct 11 16:29:15 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 16:29:15 +0200 (CEST) Subject: [pypy-svn] r58983 - pypy/build/bot2/pypybuildbot Message-ID: <20081011142915.5B12916A23E@codespeak.net> Author: arigo Date: Sat Oct 11 16:29:14 2008 New Revision: 58983 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Use "trunk" as the default branch. Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Sat Oct 11 16:29:14 2008 @@ -71,7 +71,7 @@ "-p.buildbot-sourcedata", "."], )) factory.addStep(source.SVN(baseURL="http://codespeak.net/svn/pypy/", - defaultBranch="branch/2.5-merge")) + defaultBranch="trunk")) class PyPyOwnTestFactory(factory.BuildFactory): From cfbolz at codespeak.net Sat Oct 11 17:08:47 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 11 Oct 2008 17:08:47 +0200 (CEST) Subject: [pypy-svn] r58985 - in pypy/dist/pypy/module/unicodedata: . test Message-ID: <20081011150847.9AC8216A1DF@codespeak.net> Author: cfbolz Date: Sat Oct 11 17:08:47 2008 New Revision: 58985 Modified: pypy/dist/pypy/module/unicodedata/compression.py pypy/dist/pypy/module/unicodedata/test/test_compression.py Log: (iko, cfbolz): Fix bugs in compression. Modified: pypy/dist/pypy/module/unicodedata/compression.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/compression.py (original) +++ pypy/dist/pypy/module/unicodedata/compression.py Sat Oct 11 17:08:47 2008 @@ -14,11 +14,14 @@ while len(finalcodes) < 2 ** BITS and stringlist: codes = {} for string in stringlist: - for stop in range(1, len(string)): - codes[string[:stop]] = codes.get(string[:stop], 0) + 1 + for stop in range(1, len(string) + 1): + if string[:stop] not in finalcodes: + codes[string[:stop]] = codes.get(string[:stop], 0) + 1 s = [(freq * (len(code) - 1), code) for (code, freq) in codes.iteritems()] s.sort() + if not s: + break newcode = s[-1][1] print repr(newcode) newstringlist = [] @@ -32,28 +35,23 @@ assert newstringlist != stringlist stringlist = newstringlist finalcodes.append(newcode) + finalcodes.sort(key=len) + finalcodes.reverse() - codetable = {} - for code in finalcodes: - codetable[code] = len(codetable) - return codetable, finalcodes + return finalcodes -def compress(codetable, s): +def compress(codelist, s): start = 0 result = "" while start < len(s): - stop = start + 1 - while stop <= len(s): - if s[start:stop + 1] not in codetable: - result += chr(codetable[s[start:stop]]) + for i in range(len(codelist)): + code = codelist[i] + if s.startswith(code, start): + result += chr(i) + start = start + len(code) break - else: - stop += 1 else: - # true only for last symbol - result += chr(codetable[s[start:]]) - start = stop - + assert 0, "bogus codelist" return result def uncompress(codelist, s): Modified: pypy/dist/pypy/module/unicodedata/test/test_compression.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/test/test_compression.py (original) +++ pypy/dist/pypy/module/unicodedata/test/test_compression.py Sat Oct 11 17:08:47 2008 @@ -5,14 +5,25 @@ thisfile = py.magic.autopath() data = thisfile.read() lines = data.splitlines() -codetable, codelist = compression.build_compression_table(lines) - -def test_tables_sanity(): - for key, value in codetable.items(): - assert codelist[value] == key +codelist = compression.build_compression_table(lines) def test_roundtrip(): for line in lines: - compressed = compression.compress(codetable, line) + compressed = compression.compress(codelist, line) decompressed = compression.uncompress(codelist, compressed) assert decompressed == line + +def test_simple(): + names = ['abe', 'abcde', 'abd', 'abab'] + codelist = compression.build_compression_table(names) + print codelist + for name in names: + compressed = compression.compress(codelist, name) + decompressed = compression.uncompress(codelist, compressed) + assert decompressed == name + +def test_simple2(): + names = ['abc', 'abc', 'abc'] + codelist = compression.build_compression_table(names) + assert set(codelist) == set(['abc', 'c', 'b', 'a']) + print codelist From fijal at codespeak.net Sat Oct 11 17:35:23 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 11 Oct 2008 17:35:23 +0200 (CEST) Subject: [pypy-svn] r58987 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test Message-ID: <20081011153523.3271A16A223@codespeak.net> Author: fijal Date: Sat Oct 11 17:35:22 2008 New Revision: 58987 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Log: (pedronis, fijal) platform part of generated makefile is sort of done Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sat Oct 11 17:35:22 2008 @@ -38,6 +38,8 @@ f.write('%s = %s\n' % (name, value)) else: write_list('%s =' % (name,), value) + if value: + f.write('\n') class Rule(object): def __init__(self, target, deps, body): @@ -47,11 +49,14 @@ def write(self, f): target, deps, body = self.target, self.deps, self.body - dep_s = ' '.join(deps) + if isinstance(deps, str): + dep_s = deps + else: + dep_s = ' '.join(deps) f.write('%s: %s\n' % (target, dep_s)) if isinstance(body, str): f.write('\t%s\n' % body) - else: + elif body: f.write('\t%s\n' % '\n\t'.join(body)) f.write('\n') @@ -168,6 +173,9 @@ pypypath = py.path.local(autopath.pypydir) + if exe_name is None: + exe_name = cfiles[0].new(ext='') + def pathrel(fpath): if fpath.dirpath() == path: return fpath.basename @@ -191,7 +199,7 @@ m = GnuMakefile() m.comment('automatically generated makefile') definitions = [ - ('PYPYDIR', str(autopath.pypy_dir)), + ('PYPYDIR', autopath.pypydir), ('TARGET', exe_name.basename), ('DEFAULT_TARGET', '$(TARGET)'), ('SOURCES', rel_cfiles), @@ -206,3 +214,26 @@ for args in definitions: m.definition(*args) + rules = [ + ('all', '$(DEFAULT_TARGET)', []), + ('$(TARGET)', '$(OBJECTS)', '$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS)'), + ('%.o', '%.c', '$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)'), + ] + + for rule in rules: + m.rule(*rule) + + return m + + def execute_makefile(self, path): + log.execute('make in %s' % (path,)) + returncode, stdout, stderr = _run_subprocess('make', ['-C', str(path)]) + if returncode != 0: + errorfile = path.join('make.errors') + errorfile.write(stderr) + stderrlines = stderr.splitlines() + for line in stderrlines[:5]: + log.ERROR(line) + if len(stderrlines) > 5: + log.ERROR('...') + raise CompilationError(stdout, stderr) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py Sat Oct 11 17:35:22 2008 @@ -19,3 +19,4 @@ r'^y: z\n\ta\n\tb\n\tced\n'] for i in expected_lines: assert re.search(i, val, re.M) + Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Sat Oct 11 17:35:22 2008 @@ -1,5 +1,8 @@ from pypy.translator.platform import host, CompilationError +from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.tool.udir import udir +from StringIO import StringIO def test_echo(): res = host.execute('echo', '42 24') @@ -7,3 +10,25 @@ res = host.execute('echo', ['42', '24']) assert res.out == '42 24\n' +def test_simple_makefile(): + tmpdir = udir.join('simple_makefile').ensure(dir=1) + cfile = tmpdir.join('test_simple_enough.c') + cfile.write(''' + #include + int main() + { + printf("42\\n"); + return 0; + } + ''') + mk = host.gen_makefile([cfile], ExternalCompilationInfo(), + path=tmpdir) + f = tmpdir.join('Makefile').open('w') + mk.write(f) + f.close() + host.execute_makefile(tmpdir) + res = host.execute(tmpdir.join('test_simple_enough')) + assert res.out == '42\n' + assert res.err == '' + assert res.returncode == 0 + From pedronis at codespeak.net Sat Oct 11 17:47:45 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 11 Oct 2008 17:47:45 +0200 (CEST) Subject: [pypy-svn] r58988 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test Message-ID: <20081011154745.EFEC616A2A5@codespeak.net> Author: pedronis Date: Sat Oct 11 17:47:45 2008 New Revision: 58988 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py Log: replacement behavior for definitions in makefiles Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sat Oct 11 17:47:45 2008 @@ -69,10 +69,17 @@ class GnuMakefile(object): def __init__(self): + self.defs = {} self.lines = [] def definition(self, name, value): - self.lines.append(Definition(name, value)) + defs = self.defs + defn = Definition(name, value) + if name in defs: + self.lines[defs[name]] = defn + else: + defs[name] = len(self.lines) + self.lines.append(defn) def rule(self, target, deps, body): self.lines.append(Rule(target, deps, body)) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py Sat Oct 11 17:47:45 2008 @@ -20,3 +20,12 @@ for i in expected_lines: assert re.search(i, val, re.M) +def test_redefinition(): + m = Makefile() + m.definition('CC', 'xxx') + m.definition('CC', 'yyy') + s = StringIO() + m.write(s) + val = s.getvalue() + assert not re.search('CC += +xxx', val, re.M) + assert re.search('CC += +yyy', val, re.M) From fijal at codespeak.net Sat Oct 11 18:03:58 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 11 Oct 2008 18:03:58 +0200 (CEST) Subject: [pypy-svn] r58989 - in pypy/branch/cbuild-refactor/pypy/translator: platform platform/test tool/test Message-ID: <20081011160358.B097016A259@codespeak.net> Author: fijal Date: Sat Oct 11 18:03:58 2008 New Revision: 58989 Added: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (contents, props changed) pypy/branch/cbuild-refactor/pypy/translator/platform/test/__init__.py (contents, props changed) pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py (contents, props changed) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py Log: (pedronis, fijal) Some rudimentary support for maemo platform. Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sat Oct 11 18:03:58 2008 @@ -146,6 +146,9 @@ def _execute_c_compiler(self, cc, args, outname): log.execute(cc + ' ' + ' '.join(args)) returncode, stdout, stderr = _run_subprocess(cc, args) + self._handle_error(returncode, stderr, stdout, outname) + + def _handle_error(self, returncode, stderr, stdout, outname): if returncode != 0: errorfile = outname.new(ext='errors') errorfile.write(stderr) Added: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Sat Oct 11 18:03:58 2008 @@ -0,0 +1,22 @@ + +from pypy.translator.platform.linux import Linux, _run_subprocess +from pypy.translator.platform import ExecutionResult, log + +def check_scratchbox(self): + if not py.path.local('/scratchbox/login').check(): + py.test.skip("No scratchbox detected") + +class Maemo(Linux): + def _execute_c_compiler(self, cc, args, outname): + log.execute('/scratchbox/login ' + cc + ' ' + ' '.join(args)) + args = [cc] + args + returncode, stdout, stderr = _run_subprocess('/scratchbox/login', args) + self._handle_error(returncode, stderr, stdout, outname) + + def execute(self, executable, args=[], env=None): + args = [str(executable)] + args + log.message('executing /scratchbox/login ' + ' '.join(args)) + returncode, stdout, stderr = _run_subprocess('/scratchbox/login', args, + env) + return ExecutionResult(returncode, stdout, stderr) + Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/__init__.py ============================================================================== Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py Sat Oct 11 18:03:58 2008 @@ -0,0 +1,10 @@ + +""" File containing maemo platform tests +""" + +from pypy.translator.platform.maemo import Maemo, check_scratchbox +from pypy.translator.platform.test.test_platform import TestPlatform as BasicTest + +class TestMaemo(BasicTest): + platform = Maemo() + strict_on_stderr = False Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Sat Oct 11 18:03:58 2008 @@ -4,98 +4,102 @@ from pypy.translator.platform import host, CompilationError, Platform from pypy.translator.tool.cbuild import ExternalCompilationInfo -def test_simple_enough(): - cfile = udir.join('test_simple_enough.c') - cfile.write(''' - #include - int main() - { - printf("42\\n"); - return 0; - } - ''') - executable = host.compile([cfile], ExternalCompilationInfo()) - res = host.execute(executable) - assert res.out == '42\n' - assert res.err == '' - assert res.returncode == 0 - -def test_two_files(): - cfile = udir.join('test_two_files.c') - cfile.write(''' - #include - int func(); - int main() - { - printf("%d\\n", func()); - return 0; - } - ''') - cfile2 = udir.join('implement1.c') - cfile2.write(''' - int func() - { - return 42; - } - ''') - executable = host.compile([cfile, cfile2], ExternalCompilationInfo()) - res = host.execute(executable) - assert res.out == '42\n' - assert res.err == '' - assert res.returncode == 0 - -def test_nice_errors(): - cfile = udir.join('test_nice_errors.c') - cfile.write('') - try: - executable = host.compile([cfile], ExternalCompilationInfo()) - except CompilationError, e: - filename = cfile.dirpath().join(cfile.purebasename + '.errors') - assert filename.read() == e.err - else: - py.test.fail("Did not raise") +class TestPlatform(object): + platform = host + strict_on_stderr = True -def test_use_eci(): - tmpdir = udir.join('use_eci').ensure(dir=1) - hfile = tmpdir.join('needed.h') - hfile.write('#define SOMEHASHDEFINE 42\n') - eci = ExternalCompilationInfo(include_dirs=[tmpdir]) - cfile = udir.join('use_eci_c.c') - cfile.write(''' - #include - #include "needed.h" - int main() - { - printf("%d\\n", SOMEHASHDEFINE); - return 0; - } - ''') - executable = host.compile([cfile], eci) - res = host.execute(executable) - assert res.out == '42\n' - assert res.err == '' - assert res.returncode == 0 - -def test_standalone_library(): - tmpdir = udir.join('standalone_library').ensure(dir=1) - c_file = tmpdir.join('stand1.c') - c_file.write(''' - #include - #include - - int main() - { - printf("%f\\n", pow(2.0, 2.0)); - }''') - if sys.platform != 'win32': - eci = ExternalCompilationInfo( - libraries = ['m'], - ) - else: - eci = ExternalCompilationInfo() - executable = host.compile([c_file], eci) - res = host.execute(executable) - assert res.out.startswith('4.0') + def check_res(self, res, expected='42\n'): + assert res.out == expected + if self.strict_on_stderr: + assert res.err == '' + assert res.returncode == 0 + + def test_simple_enough(self): + cfile = udir.join('test_simple_enough.c') + cfile.write(''' + #include + int main() + { + printf("42\\n"); + return 0; + } + ''') + executable = self.platform.compile([cfile], ExternalCompilationInfo()) + res = self.platform.execute(executable) + self.check_res(res) + + def test_two_files(self): + cfile = udir.join('test_two_files.c') + cfile.write(''' + #include + int func(); + int main() + { + printf("%d\\n", func()); + return 0; + } + ''') + cfile2 = udir.join('implement1.c') + cfile2.write(''' + int func() + { + return 42; + } + ''') + executable = self.platform.compile([cfile, cfile2], ExternalCompilationInfo()) + res = self.platform.execute(executable) + self.check_res(res) + + def test_nice_errors(self): + cfile = udir.join('test_nice_errors.c') + cfile.write('') + try: + executable = self.platform.compile([cfile], ExternalCompilationInfo()) + except CompilationError, e: + filename = cfile.dirpath().join(cfile.purebasename + '.errors') + assert filename.read() == e.err + else: + py.test.fail("Did not raise") + + def test_use_eci(self): + tmpdir = udir.join('use_eci').ensure(dir=1) + hfile = tmpdir.join('needed.h') + hfile.write('#define SOMEHASHDEFINE 42\n') + eci = ExternalCompilationInfo(include_dirs=[tmpdir]) + cfile = udir.join('use_eci_c.c') + cfile.write(''' + #include + #include "needed.h" + int main() + { + printf("%d\\n", SOMEHASHDEFINE); + return 0; + } + ''') + executable = self.platform.compile([cfile], eci) + res = self.platform.execute(executable) + self.check_res(res) + + def test_standalone_library(self): + tmpdir = udir.join('standalone_library').ensure(dir=1) + c_file = tmpdir.join('stand1.c') + c_file.write(''' + #include + #include + + int main() + { + printf("%f\\n", pow(2.0, 2.0)); + }''') + if sys.platform != 'win32': + eci = ExternalCompilationInfo( + libraries = ['m'], + ) + else: + eci = ExternalCompilationInfo() + executable = self.platform.compile([c_file], eci) + res = self.platform.execute(executable) + assert res.out.startswith('4.0') def test_equality(): Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/test/test_cbuild.py Sat Oct 11 18:03:58 2008 @@ -1,8 +1,7 @@ import py, sys from pypy.tool.udir import udir -from pypy.translator.tool.cbuild import build_executable, \ - ExternalCompilationInfo, compile_c_module +from pypy.translator.tool.cbuild import ExternalCompilationInfo from subprocess import Popen, PIPE, STDOUT from pypy.rlib.pyplatform import Maemo @@ -120,42 +119,13 @@ ExternalCompilationInfo.from_config_tool, 'dxowqbncpqympqhe-config') + def test_platforms(self): + from pypy.translator.platform import Platform - - - -class Stuff: - - def checkscratchbox(self): - if not py.path.local('/scratchbox/login').check(): - py.test.skip("No scratchbox detected") - - def test_standalone_maemo(self): - self.checkscratchbox() - # XXX skip if there is no scratchbox - tmpdir = self.tmpdir - c_file = tmpdir.join('stand1.c') - c_file.write(''' - #include - #include + class Maemo(Platform): + def __init__(self, cc=None): + self.cc = cc - int main() - { - printf("%f\\n", pow(2.0, 2.0)); - return 0; - }''') - if sys.platform == 'win32': - py.test.skip("No cross-compilation on windows yet") - else: - eci = ExternalCompilationInfo(platform=Maemo(), - libraries=['m']) - output = build_executable([c_file], eci) - py.test.raises(py.process.cmdexec.Error, py.process.cmdexec, output) - result = eci.platform.execute(output) - assert result.startswith('4.0') - - def test_platforms(self): - self.checkscratchbox() eci = ExternalCompilationInfo(platform=Maemo()) eci2 = ExternalCompilationInfo() assert eci != eci2 From fijal at codespeak.net Sat Oct 11 18:09:35 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 11 Oct 2008 18:09:35 +0200 (CEST) Subject: [pypy-svn] r58990 - in pypy/branch/cbuild-refactor/pypy/translator/c: . test Message-ID: <20081011160935.BA27716A164@codespeak.net> Author: fijal Date: Sat Oct 11 18:09:34 2008 New Revision: 58990 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Log: (pedronis, fijal) Delete bogus code (effect of C-c C-v), skip some tests Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Sat Oct 11 18:09:34 2008 @@ -219,110 +219,6 @@ if self.standalone: self.gen_makefile(targetdir) return cfile - - def gen_makefile(self, targetdir): - def write_list(lst, prefix): - for i, fn in enumerate(lst): - print >> f, prefix, fn, - if i < len(lst)-1: - print >> f, '\\' - else: - print >> f - prefix = ' ' * len(prefix) - - self.eci = self.eci.merge(ExternalCompilationInfo( - includes=['.', str(self.targetdir)])) - compiler = self.getccompiler() - - #self.adaptflags(compiler) - assert self.config.translation.gcrootfinder != "llvmgc" - cfiles = [] - ofiles = [] - gcmapfiles = [] - for fn in compiler.cfilenames: - fn = py.path.local(fn) - if fn.dirpath() == targetdir: - name = fn.basename - else: - assert fn.dirpath().dirpath() == udir - name = '../' + fn.relto(udir) - - name = name.replace("\\", "/") - cfiles.append(name) - if self.config.translation.gcrootfinder == "asmgcc": - ofiles.append(name[:-2] + '.s') - gcmapfiles.append(name[:-2] + '.gcmap') - else: - ofiles.append(name[:-2] + '.o') - - if self.config.translation.cc: - cc = self.config.translation.cc - else: - cc = self.eci.platform.get_compiler() - if cc is None: - cc = 'gcc' - make_no_prof = '' - if self.has_profopt(): - profopt = self.config.translation.profopt - default_target = 'profopt' - # XXX horrible workaround for a bug of profiling in gcc on - # OS X with functions containing a direct call to fork() - non_profilable = [] - assert len(compiler.cfilenames) == len(ofiles) - for fn, oname in zip(compiler.cfilenames, ofiles): - fn = py.path.local(fn) - if '/*--no-profiling-for-this-file!--*/' in fn.read(): - non_profilable.append(oname) - if non_profilable: - make_no_prof = '$(MAKE) %s' % (' '.join(non_profilable),) - else: - profopt = '' - default_target = '$(TARGET)' - - f = targetdir.join('Makefile').open('w') - print >> f, '# automatically generated Makefile' - print >> f - print >> f, 'PYPYDIR =', autopath.pypydir - print >> f - print >> f, 'TARGET =', py.path.local(compiler.outputfilename).basename - print >> f - print >> f, 'DEFAULT_TARGET =', default_target - print >> f - write_list(cfiles, 'SOURCES =') - print >> f - if self.config.translation.gcrootfinder == "asmgcc": - write_list(ofiles, 'ASMFILES =') - write_list(gcmapfiles, 'GCMAPFILES =') - print >> f, 'OBJECTS = $(ASMFILES) gcmaptable.s' - else: - print >> f, 'GCMAPFILES =' - write_list(ofiles, 'OBJECTS =') - print >> f - def makerel(path): - rel = py.path.local(path).relto(py.path.local(autopath.pypydir)) - if rel: - return os.path.join('$(PYPYDIR)', rel) - else: - return path - args = ['-l'+libname for libname in self.eci.libraries] - print >> f, 'LIBS =', ' '.join(args) - args = ['-L'+makerel(path) for path in self.eci.library_dirs] - print >> f, 'LIBDIRS =', ' '.join(args) - args = ['-I'+makerel(path) for path in self.eci.include_dirs] - write_list(args, 'INCLUDEDIRS =') - print >> f - print >> f, 'CFLAGS =', ' '.join(compiler.compile_extra) - print >> f, 'LDFLAGS =', ' '.join(compiler.link_extra) - if self.config.translation.thread: - print >> f, 'TFLAGS = ' + '-pthread' - else: - print >> f, 'TFLAGS = ' + '' - print >> f, 'PROFOPT = ' + profopt - print >> f, 'MAKENOPROF = ' + make_no_prof - print >> f, 'CC = ' + cc - print >> f - print >> f, MAKEFILE.strip() - f.close() class ModuleWithCleanup(object): def __init__(self, mod): @@ -519,6 +415,7 @@ compiler.link_extra.append(self.config.translation.linkerflags) def gen_makefile(self, targetdir): + return def write_list(lst, prefix): for i, fn in enumerate(lst): print >> f, prefix, fn, Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Sat Oct 11 18:09:34 2008 @@ -189,6 +189,7 @@ assert data.strip() == "OK" def test_separate_files(): + py.test.skip("Skip for now") # One file in translator/c/src fname = py.path.local(pypydir).join( 'translator', 'c', 'src', 'll_strtod.h') @@ -227,6 +228,7 @@ assert " ll_strtod.o" in makefile def test_cross_compilation(): + py.test.skip("Skip for now") from pypy.rlib.pyplatform import Platform from pypy.config.translationoption import set_platform From fijal at codespeak.net Sat Oct 11 18:20:18 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 11 Oct 2008 18:20:18 +0200 (CEST) Subject: [pypy-svn] r58991 - in pypy/branch/cbuild-refactor/pypy: config translator/platform Message-ID: <20081011162018.E078816A258@codespeak.net> Author: fijal Date: Sat Oct 11 18:20:16 2008 New Revision: 58991 Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Log: (fijal, pedronis) get/set platform. Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/config/translationoption.py (original) +++ pypy/branch/cbuild-refactor/pypy/config/translationoption.py Sat Oct 11 18:20:16 2008 @@ -357,5 +357,6 @@ set_platform(translateconfig.platform, config.translation.cc) def get_platform(config): - from pypy.translator.platform import host - return host + # XXX use config + from pypy.translator.platform import platform + return platform Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Sat Oct 11 18:20:16 2008 @@ -67,8 +67,13 @@ def set_platform(new_platform, cc): global platform - assert new_platform == 'host' log.msg("Setting platform to %r cc=%s" % (new_platform,cc)) - # XXX fix - platform = host + if new_platform == 'host': + platform = host.__class__(cc) + elif new_platform == 'maemo': + from pypy.translator.platform.maemo import Maemo + platform = Maemo(cc) + else: + raise NotImplementedError("platform = %s" % (new_platform,)) + Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sat Oct 11 18:20:16 2008 @@ -96,7 +96,9 @@ link_flags = ['-pthread'] cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] - def __init__(self, cc='gcc'): + def __init__(self, cc=None): + if cc is None: + cc = 'gcc' self.cc = cc def _libs(self, libraries): From pedronis at codespeak.net Sat Oct 11 18:24:13 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 11 Oct 2008 18:24:13 +0200 (CEST) Subject: [pypy-svn] r58992 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test Message-ID: <20081011162413.3503B169E39@codespeak.net> Author: pedronis Date: Sat Oct 11 18:24:11 2008 New Revision: 58992 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py Log: (fjal, pedronis) properly skip maemo test if there is no scratchbox Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Sat Oct 11 18:24:11 2008 @@ -1,8 +1,8 @@ - +import py from pypy.translator.platform.linux import Linux, _run_subprocess from pypy.translator.platform import ExecutionResult, log -def check_scratchbox(self): +def check_scratchbox(): if not py.path.local('/scratchbox/login').check(): py.test.skip("No scratchbox detected") Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py Sat Oct 11 18:24:11 2008 @@ -8,3 +8,6 @@ class TestMaemo(BasicTest): platform = Maemo() strict_on_stderr = False + + def setup_class(cls): + check_scratchbox() From xoraxax at codespeak.net Sat Oct 11 18:24:56 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 11 Oct 2008 18:24:56 +0200 (CEST) Subject: [pypy-svn] r58993 - in pypy/build/benchmem: . testing Message-ID: <20081011162456.C752D16A1AC@codespeak.net> Author: xoraxax Date: Sat Oct 11 18:24:55 2008 New Revision: 58993 Modified: pypy/build/benchmem/runbench.py pypy/build/benchmem/testing/test_benchtool.py Log: (hpk, xoraxax) Add new startup time benchmark. Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Sat Oct 11 18:24:55 2008 @@ -55,6 +55,45 @@ popen.wait() +class BenchRunnerBaseTime(BenchRunner): + def __init__(self, executable, logpath, options): + self.executable = executable + self.executable_full_path = py.path.local.sysfind(executable) + self.logpath = py.path.local(logpath) + self.logstream = self.logpath.open("a") + self.numiter = options.basetime_numiter + + def write_benchheader(self): + print >>self.logstream, self.SEPBENCH + print >>self.logstream, "#benchtype=basetime" + print >>self.logstream, "#executable=%s" %(str(self.executable ),) + print >>self.logstream + + def timecommand(self, cmd): + cmds = "time -p " + cmd + self.log("running %r for %i times" % (cmds, self.numiter)) + alltimes = [] + for _ in xrange(self.numiter): + popen = Popen(cmds, shell=True, stderr=PIPE, close_fds=True) + if popen.wait(): + raise Exception('Error in command ' + cmds) + timelines = popen.stderr.read().strip().splitlines()[-3:] + times = {} + for line in timelines: + name, time = line.split(" ", 1) + times[name] = float(time) + alltimes.append(times) + return alltimes + + def run(self): + self.write_benchheader() + for name, cmdpostfix in (('site', '-c pass'), ('nosite', '-S -c pass'), + ('importos', '-S -c "import os"')): + cmd = "%s %s " % (self.executable, cmdpostfix) + times = self.timecommand(cmd) + print >>self.logstream, "%s:%r" % (name, times) + + class BenchRunnerObjsize(BenchRunner): def __init__(self, executable, logpath, options): self.executable = executable @@ -257,6 +296,27 @@ self.executable = executable +class BasetimeResult(Result): + benchtype = 'basetime' + def __init__(self, timings, executable): + self.timings = timings + self.executable = executable + self.mintimings = [] + for name, timing in timings: + self.mintimings.append((name, min(timing, key=lambda x: x['real']))) + + @classmethod + def parse(cls, lnstream, kw): + timings = [] + for lineno, line in lnstream: + if line.strip() == BenchRunner.SEPBENCH: + break + name, data = line.split(":", 1) + times = eval(data) + timings.append((name, times)) + return cls(timings, **kw) + + class Mappings(object): HEAP, CODE, DATA = object(), object(), object() @@ -311,7 +371,9 @@ parser.add_option("-a", "--append", action="store_true", dest="append", default=False, help="append to logfile") parser.add_option("-n", "--numiter", action="store", dest="numiter", - default=100000, help="number of iterations") + default=1000, help="number of iterations") +parser.add_option("--basetime-numiter", action="store", dest="basetime_numiter", + default=10, help="number of iterations for base startup time") def getbenchlog(options): benchlog = options.benchlog @@ -340,6 +402,8 @@ return BenchRunnerObjsize if benchtype == "basesize": return BenchRunnerBaseSize + if benchtype == "basetime": + return BenchRunnerBaseTime if __name__ == '__main__': (options, args) = parser.parse_args() Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Sat Oct 11 18:24:55 2008 @@ -232,3 +232,23 @@ assert result2.snapshot.heap_private() - result1.snapshot.heap_private() < 21 report.CheckpointDetails(resultset).run() # shouldnt do anything +def test_startuptime_half_functional(): + tmpdir = py.test.ensuretemp("test_startuptime") + script = py.path.local(runbench.__file__).dirpath("runbench.py") + benchlog = tmpdir.join("benchlog") + py.process.cmdexec("%s -e python2.5,python2.5 --benchlog=%s basetime" % (script, benchlog)) + + resultset = runbench.ResultSet() + resultset.parse(benchlog) + + assert len(resultset.results) == 2 + result1, result2 = resultset.results + assert result1.benchtype == 'basetime' + assert result1.executable.endswith('python2.5') + report.CheckpointDetails(resultset).run() # shouldnt do anything + + for name, timing in result1.mintimings: + assert timing['real'] >= timing['user'] + timing['sys'] - 0.02 + # -0.02 is some skew for rounding problems + assert timing['real'] > 0 + From hpk at codespeak.net Sat Oct 11 18:30:56 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 11 Oct 2008 18:30:56 +0200 (CEST) Subject: [pypy-svn] r58994 - in pypy/build/benchmem: . testing Message-ID: <20081011163056.82BDE16A263@codespeak.net> Author: hpk Date: Sat Oct 11 18:30:56 2008 New Revision: 58994 Modified: pypy/build/benchmem/report.py pypy/build/benchmem/testing/test_benchtool.py Log: intermediate checkin Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Sat Oct 11 18:30:56 2008 @@ -162,6 +162,8 @@ return [r.executable for r in self.resultset.results] def run(self): + if not self.resultset: + return tw = py.io.TerminalWriter() tw.sep("=", "Basesize of interpreters") executables = self.getexecutables() Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Sat Oct 11 18:30:56 2008 @@ -252,3 +252,19 @@ # -0.02 is some skew for rounding problems assert timing['real'] > 0 +def test_basetime_functional(): + tmpdir = py.test.ensuretemp("test_basetime_functional") + script = py.path.local(runbench.__file__).dirpath("runbench.py") + benchlog = tmpdir.join("benchlog") + py.process.cmdexec("%s -e python2.5,python2.5 --benchlog=%s basetime" % (script, benchlog)) + + report = script.dirpath("report.py") + old = tmpdir.chdir() + try: + print "Reporter" + out = py.process.cmdexec("%s --benchlog %s" %(report, benchlog,)) + assert out.lower().find("basetime") != -1 + finally: + old.chdir() + + From hpk at codespeak.net Sat Oct 11 18:54:30 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 11 Oct 2008 18:54:30 +0200 (CEST) Subject: [pypy-svn] r58999 - in pypy/build/benchmem: . testing Message-ID: <20081011165430.DB6DF16A29D@codespeak.net> Author: hpk Date: Sat Oct 11 18:54:30 2008 New Revision: 58999 Modified: pypy/build/benchmem/report.py pypy/build/benchmem/testing/test_benchtool.py Log: (xoraxax,hpk) add report for startup time Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Sat Oct 11 18:54:30 2008 @@ -206,6 +206,31 @@ filter(group=HEAP, inv=True).rss) tw.line(asciitable(rows)) +class BaseTimeOfInterpreters: + def __init__(self, resultset): + self.resultset = resultset.filter(benchtype="basetime") + + def getexecutables(self): + return [r.executable for r in self.resultset.results] + + def run(self): + if not self.resultset: + return + tw = py.io.TerminalWriter() + tw.sep("=", "Basetime of interpreters") + # result.mintimings -> [(name, timings_dict)] + executables = self.getexecutables() + row0 = "run real user sys".split() + rows = [row0] + names = [x[0] for x in self.resultset.results[0].mintimings] + for selectname in names: + for result in self.resultset.results: + for name, timing in result.mintimings: + if name == selectname: + rows.append(["%s-%s" %(result.executable, name), + timing['real'], timing['user'], timing['sys']]) + tw.line(asciitable(rows)) + if __name__ == "__main__": options, args = parser.parse_args() @@ -217,6 +242,7 @@ CheckpointDetails(resultset).run() IncrementalSizePerBench(resultset).run() BaseSizeOfInterpreters(resultset).run() + BaseTimeOfInterpreters(resultset).run() if options.gnuplot: Gnuplot(resultset).run() Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Sat Oct 11 18:54:30 2008 @@ -232,8 +232,8 @@ assert result2.snapshot.heap_private() - result1.snapshot.heap_private() < 21 report.CheckpointDetails(resultset).run() # shouldnt do anything -def test_startuptime_half_functional(): - tmpdir = py.test.ensuretemp("test_startuptime") +def test_basetime_half_functional(): + tmpdir = py.test.ensuretemp("test_basetime_half_functional") script = py.path.local(runbench.__file__).dirpath("runbench.py") benchlog = tmpdir.join("benchlog") py.process.cmdexec("%s -e python2.5,python2.5 --benchlog=%s basetime" % (script, benchlog)) From cfbolz at codespeak.net Sat Oct 11 19:01:33 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 11 Oct 2008 19:01:33 +0200 (CEST) Subject: [pypy-svn] r59001 - pypy/dist/pypy/module/unicodedata Message-ID: <20081011170133.B659B16A22C@codespeak.net> Author: cfbolz Date: Sat Oct 11 19:01:32 2008 New Revision: 59001 Modified: pypy/dist/pypy/module/unicodedata/compression.py Log: (iko, cfbolz): RPythonify Modified: pypy/dist/pypy/module/unicodedata/compression.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/compression.py (original) +++ pypy/dist/pypy/module/unicodedata/compression.py Sat Oct 11 19:01:32 2008 @@ -18,7 +18,7 @@ if string[:stop] not in finalcodes: codes[string[:stop]] = codes.get(string[:stop], 0) + 1 - s = [(freq * (len(code) - 1), code) for (code, freq) in codes.iteritems()] + s = [((freq - 1) * (len(code) - 1), code) for (code, freq) in codes.iteritems()] s.sort() if not s: break @@ -41,14 +41,13 @@ return finalcodes def compress(codelist, s): - start = 0 result = "" - while start < len(s): + while s: for i in range(len(codelist)): code = codelist[i] - if s.startswith(code, start): + if s.startswith(code): result += chr(i) - start = start + len(code) + s = s[len(code):] break else: assert 0, "bogus codelist" From arigo at codespeak.net Sat Oct 11 19:11:49 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 19:11:49 +0200 (CEST) Subject: [pypy-svn] r59003 - pypy/branch/getslice Message-ID: <20081011171149.3344F16A272@codespeak.net> Author: arigo Date: Sat Oct 11 19:11:48 2008 New Revision: 59003 Removed: pypy/branch/getslice/ Log: Kill merged branch. From hpk at codespeak.net Sat Oct 11 19:13:12 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 11 Oct 2008 19:13:12 +0200 (CEST) Subject: [pypy-svn] r59004 - pypy/build/benchmem Message-ID: <20081011171312.CF8DC16A28E@codespeak.net> Author: hpk Date: Sat Oct 11 19:13:12 2008 New Revision: 59004 Modified: pypy/build/benchmem/runbench.py Log: (xoraxax,hpk) add optparse benchmark Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Sat Oct 11 19:13:12 2008 @@ -88,7 +88,9 @@ def run(self): self.write_benchheader() for name, cmdpostfix in (('site', '-c pass'), ('nosite', '-S -c pass'), - ('importos', '-S -c "import os"')): + ('importos', '-S -c "import os"'), + ('importoptparse', '-S -c "import optparse"'), + ): cmd = "%s %s " % (self.executable, cmdpostfix) times = self.timecommand(cmd) print >>self.logstream, "%s:%r" % (name, times) @@ -404,6 +406,7 @@ return BenchRunnerBaseSize if benchtype == "basetime": return BenchRunnerBaseTime + assert 0,benchtype if __name__ == '__main__': (options, args) = parser.parse_args() From arigo at codespeak.net Sat Oct 11 18:44:31 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 18:44:31 +0200 (CEST) Subject: [pypy-svn] r58998 - pypy/trunk/pypy/objspace/std/test Message-ID: <20081011164431.A57D416A1F8@codespeak.net> Author: arigo Date: Sat Oct 11 18:44:30 2008 New Revision: 58998 Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Log: Remove this test, which is now out-of-date and has an up-to-date duplicate. Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Sat Oct 11 18:44:30 2008 @@ -547,11 +547,6 @@ raises(TypeError, u'abcdefghijklmn'.rindex, u'abc', 0, 0.0) raises(TypeError, u'abcdefghijklmn'.rindex, u'abc', -10.0, 30) - def test_len_iter(self): - assert len(iter(u"abcdef\uffff")) == 7 - for i in range(10): - assert len(iter(unicode(i))) == 1 - def test_rfind(self): assert u'abcdefghiabc'.rfind(u'abc') == 9 assert u'abcdefghiabc'.rfind(u'') == 12 From arigo at codespeak.net Sat Oct 11 18:33:39 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 18:33:39 +0200 (CEST) Subject: [pypy-svn] r58995 - in pypy/trunk/pypy: module/__builtin__ module/__builtin__/test objspace/std objspace/std/test Message-ID: <20081011163339.0AB0816A240@codespeak.net> Author: arigo Date: Sat Oct 11 18:33:38 2008 New Revision: 58995 Modified: pypy/trunk/pypy/module/__builtin__/app_functional.py pypy/trunk/pypy/module/__builtin__/functional.py pypy/trunk/pypy/module/__builtin__/test/test_functional.py pypy/trunk/pypy/objspace/std/dictmultiobject.py pypy/trunk/pypy/objspace/std/dictobject.py pypy/trunk/pypy/objspace/std/iterobject.py pypy/trunk/pypy/objspace/std/rangeobject.py pypy/trunk/pypy/objspace/std/ropeobject.py pypy/trunk/pypy/objspace/std/ropeunicodeobject.py pypy/trunk/pypy/objspace/std/setobject.py pypy/trunk/pypy/objspace/std/test/test_dictobject.py pypy/trunk/pypy/objspace/std/test/test_iterobject.py pypy/trunk/pypy/objspace/std/test/test_rangeobject.py pypy/trunk/pypy/objspace/std/test/test_stringobject.py pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Log: Following CPython 2.5, remove __len__ on all iterator types. This should be reintroduced as __length_hint__ methods at some point; that's why I only commented the code out. Modified: pypy/trunk/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/app_functional.py (original) +++ pypy/trunk/pypy/module/__builtin__/app_functional.py Sat Oct 11 18:33:38 2008 @@ -317,10 +317,11 @@ return item raise StopIteration - def __len__(self): - if self.remaining > len(self.seq): - self.remaining = 0 - return self.remaining +# XXX __length_hint__() +## def __len__(self): +## if self.remaining > len(self.seq): +## self.remaining = 0 +## return self.remaining def __reduce__(self): tup = (self.seq, self.remaining) Modified: pypy/trunk/pypy/module/__builtin__/functional.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/functional.py (original) +++ pypy/trunk/pypy/module/__builtin__/functional.py Sat Oct 11 18:33:38 2008 @@ -259,7 +259,8 @@ W_XRangeIterator.typedef = TypeDef("rangeiterator", __iter__ = interp2app(W_XRangeIterator.descr_iter), - __len__ = interp2app(W_XRangeIterator.descr_len), +# XXX __length_hint__() +## __len__ = interp2app(W_XRangeIterator.descr_len), next = interp2app(W_XRangeIterator.descr_next), __reduce__ = interp2app(W_XRangeIterator.descr_reduce), ) Modified: pypy/trunk/pypy/module/__builtin__/test/test_functional.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/test/test_functional.py (original) +++ pypy/trunk/pypy/module/__builtin__/test/test_functional.py Sat Oct 11 18:33:38 2008 @@ -110,15 +110,10 @@ x = xrange(2, 9, 3) it = iter(x) assert iter(it) is it - assert len(it) == 3 assert it.next() == 2 - assert len(it) == 2 assert it.next() == 5 - assert len(it) == 1 assert it.next() == 8 - assert len(it) == 0 raises(StopIteration, it.next) - assert len(it) == 0 # test again, to make sure that xrange() is not its own iterator assert iter(x).next() == 2 @@ -126,16 +121,12 @@ def test_reversed(self): r = reversed("hello") assert iter(r) is r - assert len(r) == 5 assert r.next() == "o" assert r.next() == "l" assert r.next() == "l" assert r.next() == "e" - assert len(r) == 1 assert r.next() == "h" - assert len(r) == 0 raises(StopIteration, r.next) - assert len(r) == 0 assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o'] raises(TypeError, reversed, reversed("hello")) Modified: pypy/trunk/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/trunk/pypy/objspace/std/dictmultiobject.py Sat Oct 11 18:33:38 2008 @@ -1294,9 +1294,10 @@ return w_result raise OperationError(space.w_StopIteration, space.w_None) -def len__DictMultiIterObject(space, w_dictiter): - iteratorimplementation = w_dictiter.iteratorimplementation - return space.wrap(iteratorimplementation.length()) +# XXX __length_hint__() +##def len__DictMultiIterObject(space, w_dictiter): +## iteratorimplementation = w_dictiter.iteratorimplementation +## return space.wrap(iteratorimplementation.length()) # ____________________________________________________________ Modified: pypy/trunk/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dictobject.py (original) +++ pypy/trunk/pypy/objspace/std/dictobject.py Sat Oct 11 18:33:38 2008 @@ -234,7 +234,7 @@ w_self.space = space w_self.content = content = w_dictobject.content w_self.len = len(content) - w_self.pos = 0 + w_self.pos = 0 # XXX only for dicttype.descr_dictiter__reduce__() w_self.setup_iterator() def setup_iterator(w_self): @@ -300,11 +300,12 @@ w_dictiter.content = None raise OperationError(space.w_StopIteration, space.w_None) -def len__DictIterObject(space, w_dictiter): - content = w_dictiter.content - if content is None or w_dictiter.len == -1: - return space.wrap(0) - return space.wrap(w_dictiter.len - w_dictiter.pos) +# XXX __length_hint__() +##def len__DictIterObject(space, w_dictiter): +## content = w_dictiter.content +## if content is None or w_dictiter.len == -1: +## return space.wrap(0) +## return space.wrap(w_dictiter.len - w_dictiter.pos) # ____________________________________________________________ Modified: pypy/trunk/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/iterobject.py (original) +++ pypy/trunk/pypy/objspace/std/iterobject.py Sat Oct 11 18:33:38 2008 @@ -75,8 +75,9 @@ w_seqiter.index += 1 return w_item -def len__SeqIter(space, w_seqiter): - return w_seqiter.getlength(space) +# XXX __length_hint__() +##def len__SeqIter(space, w_seqiter): +## return w_seqiter.getlength(space) def iter__FastTupleIter(space, w_seqiter): @@ -95,8 +96,9 @@ w_seqiter.index = index + 1 return w_item -def len__FastTupleIter(space, w_seqiter): - return w_seqiter.getlength(space) +# XXX __length_hint__() +##def len__FastTupleIter(space, w_seqiter): +## return w_seqiter.getlength(space) def iter__FastListIter(space, w_seqiter): @@ -115,8 +117,9 @@ w_seqiter.index = index + 1 return w_item -def len__FastListIter(space, w_seqiter): - return w_seqiter.getlength(space) +# XXX __length_hint__() +##def len__FastListIter(space, w_seqiter): +## return w_seqiter.getlength(space) def iter__ReverseSeqIter(space, w_seqiter): @@ -135,19 +138,20 @@ raise OperationError(space.w_StopIteration, space.w_None) return w_item -def len__ReverseSeqIter(space, w_seqiter): - if w_seqiter.w_seq is None: - return space.wrap(0) - index = w_seqiter.index+1 - w_length = space.len(w_seqiter.w_seq) - # if length of sequence is less than index :exhaust iterator - if space.is_true(space.gt(space.wrap(w_seqiter.index), w_length)): - w_len = space.wrap(0) - w_seqiter.w_seq = None - else: - w_len =space.wrap(index) - if space.is_true(space.lt(w_len,space.wrap(0))): - w_len = space.wrap(0) - return w_len +# XXX __length_hint__() +##def len__ReverseSeqIter(space, w_seqiter): +## if w_seqiter.w_seq is None: +## return space.wrap(0) +## index = w_seqiter.index+1 +## w_length = space.len(w_seqiter.w_seq) +## # if length of sequence is less than index :exhaust iterator +## if space.is_true(space.gt(space.wrap(w_seqiter.index), w_length)): +## w_len = space.wrap(0) +## w_seqiter.w_seq = None +## else: +## w_len =space.wrap(index) +## if space.is_true(space.lt(w_len,space.wrap(0))): +## w_len = space.wrap(0) +## return w_len register_all(vars()) Modified: pypy/trunk/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/rangeobject.py (original) +++ pypy/trunk/pypy/objspace/std/rangeobject.py Sat Oct 11 18:33:38 2008 @@ -195,15 +195,16 @@ w_rangeiter.index += 1 return w_item -def len__RangeIter(space, w_rangeiter): - if w_rangeiter.w_seq is None: - return wrapint(space, 0) - index = w_rangeiter.index - w_length = space.len(w_rangeiter.w_seq) - w_len = space.sub(w_length, wrapint(space, index)) - if space.is_true(space.lt(w_len, wrapint(space, 0))): - w_len = wrapint(space, 0) - return w_len +# XXX __length_hint__() +##def len__RangeIter(space, w_rangeiter): +## if w_rangeiter.w_seq is None: +## return wrapint(space, 0) +## index = w_rangeiter.index +## w_length = space.len(w_rangeiter.w_seq) +## w_len = space.sub(w_length, wrapint(space, index)) +## if space.is_true(space.lt(w_len, wrapint(space, 0))): +## w_len = wrapint(space, 0) +## return w_len registerimplementation(W_RangeListObject) registerimplementation(W_RangeIterObject) Modified: pypy/trunk/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeobject.py Sat Oct 11 18:33:38 2008 @@ -867,15 +867,16 @@ w_ropeiter.index += 1 return w_item -def len__RopeIter(space, w_ropeiter): - if w_ropeiter.node is None: - return wrapint(space, 0) - index = w_ropeiter.index - length = w_ropeiter.node.length() - result = length - index - if result < 0: - return wrapint(space, 0) - return wrapint(space, result) +# XXX __length_hint__() +##def len__RopeIter(space, w_ropeiter): +## if w_ropeiter.node is None: +## return wrapint(space, 0) +## index = w_ropeiter.index +## length = w_ropeiter.node.length() +## result = length - index +## if result < 0: +## return wrapint(space, 0) +## return wrapint(space, result) # register all methods from pypy.objspace.std import stringtype Modified: pypy/trunk/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeunicodeobject.py Sat Oct 11 18:33:38 2008 @@ -949,15 +949,16 @@ w_ropeiter.index += 1 return w_item -def len__RopeUnicodeIter(space, w_ropeiter): - if w_ropeiter.node is None: - return space.wrap(0) - index = w_ropeiter.index - length = w_ropeiter.node.length() - result = length - index - if result < 0: - return space.wrap(0) - return space.wrap(result) +# XXX __length_hint__() +##def len__RopeUnicodeIter(space, w_ropeiter): +## if w_ropeiter.node is None: +## return space.wrap(0) +## index = w_ropeiter.index +## length = w_ropeiter.node.length() +## result = length - index +## if result < 0: +## return space.wrap(0) +## return space.wrap(result) import unicodetype register_all(vars(), unicodetype) Modified: pypy/trunk/pypy/objspace/std/setobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/setobject.py (original) +++ pypy/trunk/pypy/objspace/std/setobject.py Sat Oct 11 18:33:38 2008 @@ -86,11 +86,12 @@ w_setiter.content = None raise OperationError(space.w_StopIteration, space.w_None) -def len__SetIterObject(space, w_setiter): - content = w_setiter.content - if content is None or w_setiter.len == -1: - return space.wrap(0) - return space.wrap(w_setiter.len - w_setiter.pos) +# XXX __length_hint__() +##def len__SetIterObject(space, w_setiter): +## content = w_setiter.content +## if content is None or w_setiter.len == -1: +## return space.wrap(0) +## return space.wrap(w_setiter.len - w_setiter.pos) # some helper functions Modified: pypy/trunk/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_dictobject.py Sat Oct 11 18:33:38 2008 @@ -450,6 +450,14 @@ else: assert False, 'Expected KeyError' + def test_no_len_on_dict_iter(self): + iterable = {1: 2, 3: 4} + raises(TypeError, len, iter(iterable)) + iterable = {"1": 2, "3": 4} + raises(TypeError, len, iter(iterable)) + iterable = {} + raises(TypeError, len, iter(iterable)) + # the minimal 'space' needed to use a W_DictObject class FakeSpace: Modified: pypy/trunk/pypy/objspace/std/test/test_iterobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_iterobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_iterobject.py Sat Oct 11 18:33:38 2008 @@ -59,117 +59,42 @@ C()) class AppTest_IterObject(object): - def setup_method(self,method): + def test_no_len_on_list_iter(self): + iterable = [1,2,3,4] + raises(TypeError, len, iter(iterable)) + + def test_no_len_on_tuple_iter(self): + iterable = (1,2,3,4) + raises(TypeError, len, iter(iterable)) - self.iterable = '' - - def test_len(self):#,iterable): - self.iterable = (1,2,3,4) - it = iter(self.iterable) - for i in reversed(range(len(it))): - assert len(it) == i+1 - x = it.next() - raises(StopIteration, it.next) - assert len(it) == 0 - - -class AppTest_lenTuple(AppTest_IterObject): - - def setup_method(self,method): - self.iterable = (1,2,3,4) - - def test_iter_len_deque(self): + def test_no_len_on_deque_iter(self): from collections import deque + iterable = deque([1,2,3,4]) + raises(TypeError, len, iter(iterable)) - iterable = deque((1,2,3,4)) - it = iter(iterable) - for i in reversed(range(len(it))): - assert len(it) == i+1 - x = it.next() - - raises(StopIteration, it.next) - assert len(it) == 0 - - def test_iter_len_reversed(self): - iterable = reversed((1,2,3,4)) - it = iter(iterable) - for i in reversed(range(len(it))): - assert len(it) == i+1 - x = it.next() - raises(StopIteration, it.next) - assert len(it) == 0 + def test_no_len_on_reversed(self): + it = reversed("foobar") + raises(TypeError, len, it) - def test_len_reversed_seqiter(self): + def test_no_len_on_reversed_seqiter(self): + # this one fails on CPython. See http://bugs.python.org/issue3689 it = reversed([5,6,7]) - assert iter(it) is it - assert len(it) == 3 - assert it.next() == 7 - assert len(it) == 2 - assert it.next() == 6 - assert len(it) == 1 - assert it.next() == 5 - assert len(it) == 0 - raises(StopIteration, it.next) - assert len(it) == 0 - - def test_mutation_list(self): - n = 5 - d = range(n) - it = iter(d) - it.next() - it.next() - assert len(it) == n-2 - d.append(n) - assert len(it) == n-1 # grow with append - d[1:] = [] - assert len(it) == 0 - assert list(it) == [] - d.extend(xrange(20)) - assert len(it) == 0 - - def test_mutation_list_reversed(self): - n = 5 - d = range(n) - it = reversed(d) - it.next() - it.next() - assert len(it) == n-2 - d.append(n) - assert len(it) == n-2 # Ignore append - d[1:] = [] - assert len(it) == 0 - assert list(it) == [] - d.extend(xrange(20)) - assert len(it) == 0 + raises(TypeError, len, it) - def test_mutation_seqiter(self): + def test_no_len_on_UserList_iter(self): from UserList import UserList - n = 5 - d = UserList(range(n)) - it = iter(d) - it.next() - it.next() - assert len(it) == n-2 - d.append(n) - assert len(it) == n-1 # grow with append - d[1:] = [] - assert len(it) == 0 - assert list(it) == [] - d.extend(xrange(20)) - assert len(it) == 0 + iterable = UserList([1,2,3,4]) + raises(TypeError, len, iter(iterable)) - def test_mutation_seqiter_reversed(self): + def test_no_len_on_UserList_reversed(self): from UserList import UserList - n = 5 - d = UserList(range(n)) - it = reversed(d) - it.next() - it.next() - assert len(it) == n-2 - d.append(n) - assert len(it) == n-2 # ignore append - d[1:] = [] - assert len(it) == 0 - assert list(it) == [] - d.extend(xrange(20)) - assert len(it) == 0 + iterable = UserList([1,2,3,4]) + raises(TypeError, len, reversed(iterable)) + + def test_no_len_on_set_iter(self): + iterable = set([1,2,3,4]) + raises(TypeError, len, iter(iterable)) + + def test_no_len_on_xrange(self): + iterable = xrange(10) + raises(TypeError, len, iter(iterable)) Modified: pypy/trunk/pypy/objspace/std/test/test_rangeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_rangeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_rangeobject.py Sat Oct 11 18:33:38 2008 @@ -120,3 +120,7 @@ it3 = seqiter_new(*args) assert it3.next() == 4 assert it3.next() == 5 + + def test_no_len_on_range_iter(self): + iterable = range(10) + raises(TypeError, len, iter(iterable)) Modified: pypy/trunk/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_stringobject.py Sat Oct 11 18:33:38 2008 @@ -721,6 +721,10 @@ s = "a" * (2**16) raises(OverflowError, s.replace, "", s) + def test_no_len_on_str_iter(self): + iterable = "hello" + raises(TypeError, len, iter(iterable)) + class AppTestPrebuilt(AppTestStringObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True}) Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Sat Oct 11 18:33:38 2008 @@ -641,3 +641,6 @@ assert unicode(Y()).__class__ is X + def test_no_len_on_str_iter(self): + iterable = u"hello" + raises(TypeError, len, iter(iterable)) From arigo at codespeak.net Sat Oct 11 19:10:44 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 19:10:44 +0200 (CEST) Subject: [pypy-svn] r59002 - pypy/trunk/pypy/interpreter/test Message-ID: <20081011171044.5283E16A272@codespeak.net> Author: arigo Date: Sat Oct 11 19:10:41 2008 New Revision: 59002 Modified: pypy/trunk/pypy/interpreter/test/test_pickle.py Log: Fix tests. Modified: pypy/trunk/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_pickle.py (original) +++ pypy/trunk/pypy/interpreter/test/test_pickle.py Sat Oct 11 19:10:41 2008 @@ -320,7 +320,7 @@ liter.next() result.next() assert type(liter) is type(result) - assert len(liter) == 6 + raises(TypeError, len, liter) assert list(liter) == list(result) def test_pickle_reversesequenceiter(self): @@ -332,7 +332,7 @@ liter.next() result.next() assert type(liter) is type(result) - assert len(liter) == 6 + raises(TypeError, len, liter) assert list(liter) == list(result) def test_pickle_dictiter(self): @@ -342,7 +342,7 @@ diter.next() pckl = pickle.dumps(diter) result = pickle.loads(pckl) - assert len(diter) == 2 + raises(TypeError, len, diter) assert list(diter) == list(result) def test_pickle_enum(self): From arigo at codespeak.net Sat Oct 11 19:01:18 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 19:01:18 +0200 (CEST) Subject: [pypy-svn] r59000 - in pypy/trunk/pypy: annotation annotation/test interpreter objspace objspace/flow objspace/flow/test objspace/std objspace/std/test rpython rpython/lltypesystem rpython/ootypesystem rpython/test translator translator/test Message-ID: <20081011170118.D872F16A247@codespeak.net> Author: arigo Date: Sat Oct 11 19:01:14 2008 New Revision: 59000 Removed: pypy/trunk/pypy/rpython/lltypesystem/rslice.py pypy/trunk/pypy/rpython/ootypesystem/rslice.py pypy/trunk/pypy/rpython/rslice.py Modified: pypy/trunk/pypy/annotation/annrpython.py pypy/trunk/pypy/annotation/binaryop.py pypy/trunk/pypy/annotation/bookkeeper.py pypy/trunk/pypy/annotation/builtin.py pypy/trunk/pypy/annotation/model.py pypy/trunk/pypy/annotation/test/test_annrpython.py pypy/trunk/pypy/annotation/unaryop.py pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/objspace/descroperation.py pypy/trunk/pypy/objspace/flow/objspace.py pypy/trunk/pypy/objspace/flow/operation.py pypy/trunk/pypy/objspace/flow/test/test_objspace.py pypy/trunk/pypy/objspace/reflective.py pypy/trunk/pypy/objspace/std/builtinshortcut.py pypy/trunk/pypy/objspace/std/listobject.py pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/std/rangeobject.py pypy/trunk/pypy/objspace/std/ropeobject.py pypy/trunk/pypy/objspace/std/ropeunicodeobject.py pypy/trunk/pypy/objspace/std/sliceobject.py pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/strsliceobject.py pypy/trunk/pypy/objspace/std/test/test_builtinshortcut.py pypy/trunk/pypy/objspace/std/test/test_listmultiobject.py pypy/trunk/pypy/objspace/std/test/test_listobject.py pypy/trunk/pypy/objspace/std/test/test_rangeobject.py pypy/trunk/pypy/objspace/std/test/test_stringobject.py pypy/trunk/pypy/objspace/std/test/test_strsliceobject.py pypy/trunk/pypy/objspace/std/test/test_tupleobject.py pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py pypy/trunk/pypy/objspace/std/tupleobject.py pypy/trunk/pypy/objspace/std/unicodeobject.py pypy/trunk/pypy/objspace/thunk.py pypy/trunk/pypy/rpython/lltypesystem/rlist.py pypy/trunk/pypy/rpython/lltypesystem/rstr.py pypy/trunk/pypy/rpython/ootypesystem/rlist.py pypy/trunk/pypy/rpython/ootypesystem/rstr.py pypy/trunk/pypy/rpython/rlist.py pypy/trunk/pypy/rpython/rstr.py pypy/trunk/pypy/rpython/rtuple.py pypy/trunk/pypy/rpython/rtyper.py pypy/trunk/pypy/rpython/test/test_rlist.py pypy/trunk/pypy/rpython/test/test_rtyper.py pypy/trunk/pypy/translator/simplify.py pypy/trunk/pypy/translator/test/test_simplify.py pypy/trunk/pypy/translator/transform.py Log: (antocuni not currently there, arigo) Merge the getslice branch, where __{get,set,del}slice__ are implemented as real space operations and multimethods. This allows quite a bit of code to be simplified, notably in the translation toolchain, which now only needs to support the {get,set,del}slice operations instead of having to worry about slice objects and newslice/{get,set,del}item pairs of operations. Modified: pypy/trunk/pypy/annotation/annrpython.py ============================================================================== --- pypy/trunk/pypy/annotation/annrpython.py (original) +++ pypy/trunk/pypy/annotation/annrpython.py Sat Oct 11 19:01:14 2008 @@ -760,10 +760,6 @@ def consider_op_newdict(self): return self.bookkeeper.newdict() - def consider_op_newslice(self, start, stop, step): - self.bookkeeper.count('newslice', start, stop, step) - return annmodel.SomeSlice(start, stop, step) - def _registeroperations(cls, model): # All unary operations Modified: pypy/trunk/pypy/annotation/binaryop.py ============================================================================== --- pypy/trunk/pypy/annotation/binaryop.py (original) +++ pypy/trunk/pypy/annotation/binaryop.py Sat Oct 11 19:01:14 2008 @@ -10,7 +10,7 @@ from pypy.annotation.model import SomeUnicodeCodePoint from pypy.annotation.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeIterator -from pypy.annotation.model import SomePBC, SomeSlice, SomeFloat, s_None +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 @@ -564,14 +564,6 @@ delitem.can_only_throw = _can_only_throw -class __extend__(pairtype(SomeSlice, SomeSlice)): - - def union((slic1, slic2)): - return SomeSlice(unioncheck(slic1.start, slic2.start), - unioncheck(slic1.stop, slic2.stop), - unioncheck(slic1.step, slic2.step)) - - class __extend__(pairtype(SomeTuple, SomeInteger)): def getitem((tup1, int2)): @@ -585,13 +577,6 @@ return unionof(*tup1.items) getitem.can_only_throw = [IndexError] -class __extend__(pairtype(SomeTuple, SomeSlice)): - - def getitem((tup, slic)): - start, stop, step = slic.constant_indices() - return SomeTuple(tup.items[start:stop:step]) - getitem.can_only_throw = [] - class __extend__(pairtype(SomeList, SomeInteger)): @@ -623,40 +608,6 @@ lst1.listdef.resize() delitem.can_only_throw = [IndexError] -def check_negative_slice(s_slice): - if isinstance(s_slice.start, SomeInteger) and not s_slice.start.nonneg: - raise TypeError("%s not proven to have non-negative start" % s_slice) - if isinstance(s_slice.stop, SomeInteger) and not s_slice.stop.nonneg and\ - getattr(s_slice.stop, 'const', 0) != -1: - raise TypeError("%s not proven to have non-negative stop" % s_slice) - -class __extend__(pairtype(SomeList, SomeSlice)): - - def getitem((lst, slic)): - check_negative_slice(slic) - return lst.listdef.offspring() - getitem.can_only_throw = [] - - def setitem((lst, slic), s_iterable): - check_negative_slice(slic) - # we need the same unifying effect as the extend() method for - # the case lst1[x:y] = lst2. - lst.method_extend(s_iterable) - setitem.can_only_throw = [] - - def delitem((lst1, slic)): - check_negative_slice(slic) - lst1.listdef.resize() - delitem.can_only_throw = [] - -class __extend__(pairtype(SomeString, SomeSlice), - pairtype(SomeUnicodeString, SomeSlice)): - - def getitem((str1, slic)): - check_negative_slice(slic) - return str1.basestringclass() - getitem.can_only_throw = [] - class __extend__(pairtype(SomeString, SomeInteger)): def getitem((str1, int2)): Modified: pypy/trunk/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/trunk/pypy/annotation/bookkeeper.py (original) +++ pypy/trunk/pypy/annotation/bookkeeper.py Sat Oct 11 19:01:14 2008 @@ -68,9 +68,6 @@ def consider_generic(self, *args): return tuple([self.typerepr(x) for x in args]) - def consider_newslice(self, s_start, s_stop, s_step): - return ':'.join([self.indexrepr(s_start), self.indexrepr(s_stop), self.steprepr(s_step)]) - def consider_list_list_eq(self, obj1, obj2): return obj1, obj2 Modified: pypy/trunk/pypy/annotation/builtin.py ============================================================================== --- pypy/trunk/pypy/annotation/builtin.py (original) +++ pypy/trunk/pypy/annotation/builtin.py Sat Oct 11 19:01:14 2008 @@ -4,7 +4,7 @@ import sys from pypy.annotation.model import SomeInteger, SomeObject, SomeChar, SomeBool -from pypy.annotation.model import SomeString, SomeTuple, SomeSlice, s_Bool +from pypy.annotation.model import SomeString, SomeTuple, s_Bool from pypy.annotation.model import SomeUnicodeCodePoint, SomeAddress from pypy.annotation.model import SomeFloat, unionof, SomeUnicodeString from pypy.annotation.model import SomePBC, SomeInstance, SomeDict @@ -249,19 +249,19 @@ getbookkeeper().warning("ignoring apply%r" % (stuff,)) return SomeObject() -def builtin_slice(*args): - bk = getbookkeeper() - if len(args) == 1: - return SomeSlice( - bk.immutablevalue(None), args[0], bk.immutablevalue(None)) - elif len(args) == 2: - return SomeSlice( - args[0], args[1], bk.immutablevalue(None)) - elif len(args) == 3: - return SomeSlice( - args[0], args[1], args[2]) - else: - raise Exception, "bogus call to slice()" +##def builtin_slice(*args): +## bk = getbookkeeper() +## if len(args) == 1: +## return SomeSlice( +## bk.immutablevalue(None), args[0], bk.immutablevalue(None)) +## elif len(args) == 2: +## return SomeSlice( +## args[0], args[1], bk.immutablevalue(None)) +## elif len(args) == 3: +## return SomeSlice( +## args[0], args[1], args[2]) +## else: +## raise Exception, "bogus call to slice()" def OSError_init(s_self, *args): Modified: pypy/trunk/pypy/annotation/model.py ============================================================================== --- pypy/trunk/pypy/annotation/model.py (original) +++ pypy/trunk/pypy/annotation/model.py Sat Oct 11 19:01:14 2008 @@ -253,25 +253,6 @@ def can_be_none(self): return True -class SomeSlice(SomeObject): - knowntype = slice - immutable = True - def __init__(self, start, stop, step): - self.start = start - self.stop = stop - self.step = step - - def constant_indices(self): - if (self.start.is_immutable_constant() and - self.stop .is_immutable_constant() and - self.step .is_immutable_constant()): - return self.start.const, self.stop.const, self.step.const - else: - raise Exception("need constant indices for this slice") - - def can_be_none(self): - return False - class SomeTuple(SomeObject): "Stands for a tuple of known length." knowntype = tuple Modified: pypy/trunk/pypy/annotation/test/test_annrpython.py ============================================================================== --- pypy/trunk/pypy/annotation/test/test_annrpython.py (original) +++ pypy/trunk/pypy/annotation/test/test_annrpython.py Sat Oct 11 19:01:14 2008 @@ -425,16 +425,6 @@ s_meth = s_example.getattr(iv(methname)) assert isinstance(s_constmeth, annmodel.SomeBuiltin) - def test_simple_slicing0(self): - a = self.RPythonAnnotator() - a.build_types(snippet.simple_slice, [list]) - g = graphof(a, snippet.simple_slice) - for block in g.iterblocks(): - for op in block.operations: - if op.opname == "newslice": - assert isinstance(a.binding(op.result), - annmodel.SomeSlice) - def test_simple_slicing(self): a = self.RPythonAnnotator() s = a.build_types(snippet.simple_slice, [list]) @@ -570,11 +560,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_slice_union(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.slice_union, [int]) - assert isinstance(s, annmodel.SomeSlice) - def test_bltin_code_frame_confusion(self): a = self.RPythonAnnotator() a.build_types(snippet.bltin_code_frame_confusion,[]) @@ -3040,6 +3025,28 @@ a.build_types(f, [str]) + def test_setslice(self): + def f(): + lst = [2, 5, 7] + lst[1:2] = [4] + return lst + + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeList) + assert not s.listdef.listitem.resized + + def test_delslice(self): + def f(): + lst = [2, 5, 7] + del lst[1:2] + return lst + + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeList) + assert s.listdef.listitem.resized + def test_listitem_no_mutating(self): from pypy.rlib.debug import check_annotation called = [] Modified: pypy/trunk/pypy/annotation/unaryop.py ============================================================================== --- pypy/trunk/pypy/annotation/unaryop.py (original) +++ pypy/trunk/pypy/annotation/unaryop.py Sat Oct 11 19:01:14 2008 @@ -24,6 +24,7 @@ 'iter', 'next', 'invert', 'type', 'issubtype', 'pos', 'neg', 'nonzero', 'abs', 'hex', 'oct', 'ord', 'int', 'float', 'long', 'id', + 'getslice', 'setslice', 'delslice', 'neg_ovf', 'abs_ovf', 'hint', 'unicode', 'unichr']) for opname in UNARY_OPERATIONS: @@ -274,6 +275,12 @@ s_item.hash() # record that we need the hash of each item return SomeInteger() + def getslice(tup, s_start, s_stop): + assert s_start.is_immutable_constant(),"tuple slicing: needs constants" + assert s_stop.is_immutable_constant(), "tuple slicing: needs constants" + items = tup.items[s_start.const:s_stop.const] + return SomeTuple(items) + class __extend__(SomeList): @@ -338,6 +345,28 @@ lst = lst.listdef.offspring() return lst + def getslice(lst, s_start, s_stop): + check_negative_slice(s_start, s_stop) + return lst.listdef.offspring() + + def setslice(lst, s_start, s_stop, s_iterable): + check_negative_slice(s_start, s_stop) + if not isinstance(s_iterable, SomeList): + raise Exception("list[start:stop] = x: x must be a list") + lst.listdef.agree(s_iterable.listdef) + # note that setslice is not allowed to resize a list in RPython + + def delslice(lst, s_start, s_stop): + check_negative_slice(s_start, s_stop) + lst.listdef.resize() + +def check_negative_slice(s_start, s_stop): + if isinstance(s_start, SomeInteger) and not s_start.nonneg: + raise TypeError("slicing: not proven to have non-negative start") + if isinstance(s_stop, SomeInteger) and not s_stop.nonneg and \ + getattr(s_stop, 'const', 0) != -1: + raise TypeError("slicing: not proven to have non-negative stop") + class __extend__(SomeDict): @@ -463,6 +492,10 @@ def method_replace(str, s1, s2): return str.basestringclass() + def getslice(str, s_start, s_stop): + check_negative_slice(s_start, s_stop) + return str.basestringclass() + class __extend__(SomeUnicodeString): def method_encode(uni, s_enc): if not s_enc.is_constant(): Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Sat Oct 11 19:01:14 2008 @@ -588,17 +588,6 @@ w_s = self.interned_strings[s] = self.wrap(s) return w_s - # support for the deprecated __getslice__, __setslice__, __delslice__ - def getslice(self, w_obj, w_start, w_stop): - w_slice = self.newslice(w_start, w_stop, self.w_None) - return self.getitem(w_obj, w_slice) - def setslice(self, w_obj, w_start, w_stop, w_sequence): - w_slice = self.newslice(w_start, w_stop, self.w_None) - self.setitem(w_obj, w_slice, w_sequence) - def delslice(self, w_obj, w_start, w_stop): - w_slice = self.newslice(w_start, w_stop, self.w_None) - self.delitem(w_obj, w_slice) - def interpclass_w(space, w_obj): """ If w_obj is a wrapped internal interpreter class instance unwrap to it, @@ -1032,6 +1021,9 @@ ('getitem', 'getitem', 2, ['__getitem__']), ('setitem', 'setitem', 3, ['__setitem__']), ('delitem', 'delitem', 2, ['__delitem__']), + ('getslice', 'getslice', 3, ['__getslice__']), + ('setslice', 'setslice', 4, ['__setslice__']), + ('delslice', 'delslice', 3, ['__delslice__']), ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), ('nonzero', 'truth', 1, ['__nonzero__']), Modified: pypy/trunk/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/pypy/objspace/descroperation.py (original) +++ pypy/trunk/pypy/objspace/descroperation.py Sat Oct 11 19:01:14 2008 @@ -228,6 +228,30 @@ space.wrap("cannot delete items from object")) return space.get_and_call_function(w_descr, w_obj, w_key) + def getslice(space, w_obj, w_start, w_stop): + w_descr = space.lookup(w_obj, '__getslice__') + if w_descr is None: + w_slice = space.newslice(w_start, w_stop, space.w_None) + return space.getitem(w_obj, w_slice) + w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) + return space.get_and_call_function(w_descr, w_obj, w_start, w_stop) + + def setslice(space, w_obj, w_start, w_stop, w_sequence): + w_descr = space.lookup(w_obj, '__setslice__') + if w_descr is None: + w_slice = space.newslice(w_start, w_stop, space.w_None) + return space.setitem(w_obj, w_slice, w_sequence) + w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) + return space.get_and_call_function(w_descr, w_obj, w_start, w_stop, w_sequence) + + def delslice(space, w_obj, w_start, w_stop): + w_descr = space.lookup(w_obj, '__delslice__') + if w_descr is None: + w_slice = space.newslice(w_start, w_stop, space.w_None) + return space.delitem(w_obj, w_slice) + w_start, w_stop = old_slice_range(space, w_obj, w_start, w_stop) + return space.get_and_call_function(w_descr, w_obj, w_start, w_stop) + def pow(space, w_obj1, w_obj2, w_obj3): w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) @@ -453,6 +477,35 @@ return (space.lookup(w_obj, '__int__') is not None or space.lookup(w_obj, '__float__') is not None) + + +# what is the maximum value slices can get on CPython? +# we need to stick to that value, because fake.py etc. +class Temp: + def __getslice__(self, i, j): + return j +slice_max = Temp()[:] +del Temp + +def old_slice_range(space, w_obj, w_start, w_stop): + """Only for backward compatibility for __getslice__()&co methods.""" + if space.is_w(w_start, space.w_None): + w_start = space.wrap(0) + else: + w_start = space.wrap(space.getindex_w(w_start, None)) + if space.is_true(space.lt(w_start, space.wrap(0))): + w_start = space.add(w_start, space.len(w_obj)) + # NB. the language ref is inconsistent with the new-style class + # behavior when w_obj doesn't implement __len__(), so we just + # ignore this case. + if space.is_w(w_stop, space.w_None): + w_stop = space.wrap(slice_max) + else: + w_stop = space.wrap(space.getindex_w(w_stop, None)) + if space.is_true(space.lt(w_stop, space.wrap(0))): + w_stop = space.add(w_stop, space.len(w_obj)) + return w_start, w_stop + # regular methods def helpers def _make_binop_impl(symbol, specialnames): @@ -649,5 +702,3 @@ 'ord', 'unichr', 'unicode']: raise Exception, "missing def for operation %s" % _name - - Modified: pypy/trunk/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/pypy/objspace/flow/objspace.py Sat Oct 11 19:01:14 2008 @@ -622,6 +622,10 @@ # annotator a lot. if arithmetic and type(result) is long: pass + # don't constant-fold getslice on lists, either + elif name == 'getslice' and type(result) is list: + pass + # otherwise, fine else: try: return self.wrap(result) Modified: pypy/trunk/pypy/objspace/flow/operation.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/operation.py (original) +++ pypy/trunk/pypy/objspace/flow/operation.py Sat Oct 11 19:01:14 2008 @@ -134,6 +134,16 @@ def lshift_ovf(x, y): return ovfcheck_lshift(x, y) +# slicing: operator.{get,set,del}slice() don't support b=None or c=None +def do_getslice(a, b, c): + return a[b:c] + +def do_setslice(a, b, c, d): + a[b:c] = d + +def do_delslice(a, b, c): + del a[b:c] + # ____________________________________________________________ # The following table can list several times the same operation name, @@ -190,6 +200,9 @@ ('delete', delete), ('userdel', userdel), ('buffer', buffer), + ('getslice', do_getslice), + ('setslice', do_setslice), + ('delslice', do_delslice), # --- operations added by graph transformations --- ('neg_ovf', neg_ovf), ('abs_ovf', abs_ovf), Modified: pypy/trunk/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/trunk/pypy/objspace/flow/test/test_objspace.py Sat Oct 11 19:01:14 2008 @@ -851,6 +851,31 @@ return foolist[0] py.test.raises(RuntimeError, "self.codetest(f)") + def test_getslice_constfold(self): + def check(f, expected): + graph = self.codetest(f) + assert graph.startblock.operations == [] + [link] = graph.startblock.exits + assert link.target is graph.returnblock + assert isinstance(link.args[0], Constant) + assert link.args[0].value == expected + + def f1(): + s = 'hello' + return s[:-2] + check(f1, 'hel') + + def f2(): + s = 'hello' + return s[:] + check(f2, 'hello') + + def f3(): + s = 'hello' + return s[-3:] + check(f3, 'llo') + + class TestFlowObjSpaceDelay(Base): def setup_class(cls): cls.space = FlowObjSpace() Modified: pypy/trunk/pypy/objspace/reflective.py ============================================================================== --- pypy/trunk/pypy/objspace/reflective.py (original) +++ pypy/trunk/pypy/objspace/reflective.py Sat Oct 11 19:01:14 2008 @@ -89,6 +89,14 @@ return parentfn(w_arg1, w_arg2, w_arg3) finally: reset_reflective_space(space, w_old_reflectivespace) + elif args == 4: + def func(self, space, w_arg1, w_arg2, w_arg3, w_arg4): + w_old_reflectivespace = get_reflective_space(space) + set_reflectivespace(space, self.w_reflectivespace) + try: + return parentfn(w_arg1, w_arg2, w_arg3, w_arg4) + finally: + reset_reflective_space(space, w_old_reflectivespace) else: raise NotImplementedError unwrap_spec = ["self", ObjSpace] + [W_Root] * args Modified: pypy/trunk/pypy/objspace/std/builtinshortcut.py ============================================================================== --- pypy/trunk/pypy/objspace/std/builtinshortcut.py (original) +++ pypy/trunk/pypy/objspace/std/builtinshortcut.py Sat Oct 11 19:01:14 2008 @@ -32,10 +32,16 @@ KNOWN_MISSING = ['getattr', # mostly non-builtins or optimized by CALL_METHOD 'setattr', 'delattr', 'userdel', # mostly for non-builtins 'get', 'set', 'delete', # uncommon (except on functions) - 'delitem', 'abs', 'hex', 'oct', # rare stuff? + 'getslice', 'setslice', 'delslice', # see below + 'delitem', # rare stuff? + 'abs', 'hex', 'oct', # rare stuff? 'pos', 'divmod', 'cmp', # rare stuff? 'float', 'long', 'coerce', # rare stuff? ] +# We cannot support {get,set,del}slice right now because +# DescrOperation.{get,set,del}slice do a bit more work than just call +# the special methods: they call old_slice_range(). See e.g. +# test_builtinshortcut.AppTestString. for _name, _, _, _specialmethods in ObjSpace.MethodTable: if _specialmethods: Modified: pypy/trunk/pypy/objspace/std/listobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/listobject.py (original) +++ pypy/trunk/pypy/objspace/std/listobject.py Sat Oct 11 19:01:14 2008 @@ -1,7 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.listtype import get_list_index -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.interpreter import gateway, baseobjspace @@ -80,6 +80,21 @@ start += step return w_res +def getslice__List_ANY_ANY(space, w_list, w_start, w_stop): + length = len(w_list.wrappeditems) + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + return W_ListObject(w_list.wrappeditems[start:stop]) + +def setslice__List_ANY_ANY_ANY(space, w_list, w_start, w_stop, w_sequence): + length = len(w_list.wrappeditems) + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + _setitem_slice_helper(space, w_list, start, 1, stop-start, w_sequence) + +def delslice__List_ANY_ANY(space, w_list, w_start, w_stop): + length = len(w_list.wrappeditems) + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + _delitem_slice_helper(space, w_list, start, 1, stop-start) + def contains__List_ANY(space, w_list, w_obj): # needs to be safe against eq_w() mutating the w_list behind our back i = 0 @@ -190,38 +205,35 @@ space.wrap("list deletion index out of range")) return space.w_None + def delitem__List_Slice(space, w_list, w_slice): start, stop, step, slicelength = w_slice.indices4(space, len(w_list.wrappeditems)) + _delitem_slice_helper(space, w_list, start, step, slicelength) +def _delitem_slice_helper(space, w_list, start, step, slicelength): if slicelength==0: return if step < 0: start = start + step * (slicelength-1) step = -step - # stop is invalid if step == 1: - _del_slice(w_list, start, start+slicelength) + assert start >= 0 + assert slicelength >= 0 + del w_list.wrappeditems[start:start+slicelength] else: items = w_list.wrappeditems n = len(items) - - recycle = [None] * slicelength i = start - # keep a reference to the objects to be removed, - # preventing side effects during destruction - recycle[0] = items[i] - for discard in range(1, slicelength): j = i+1 i += step while j < i: items[j-discard] = items[j] j += 1 - recycle[discard] = items[i] j = i+1 while j < n: @@ -229,13 +241,7 @@ j += 1 start = n - slicelength assert start >= 0 # annotator hint - # XXX allow negative indices in rlist del items[start:] - # now we can destruct recycle safely, regardless of - # side-effects to the list - del recycle[:] - - return space.w_None def setitem__List_ANY_ANY(space, w_list, w_index, w_any): idx = get_list_index(space, w_index) @@ -246,23 +252,25 @@ space.wrap("list index out of range")) return space.w_None -def setitem__List_Slice_List(space, w_list, w_slice, w_list2): - l = w_list2.wrappeditems - return _setitem_slice_helper(space, w_list, w_slice, l, len(l)) - def setitem__List_Slice_ANY(space, w_list, w_slice, w_iterable): - l = space.unpackiterable(w_iterable) - return _setitem_slice_helper(space, w_list, w_slice, l, len(l)) - -def _setitem_slice_helper(space, w_list, w_slice, sequence2, len2): oldsize = len(w_list.wrappeditems) start, stop, step, slicelength = w_slice.indices4(space, oldsize) + _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable) + +def _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable): + if isinstance(w_iterable, W_ListObject): + sequence2 = w_iterable.wrappeditems + else: + sequence2 = space.unpackiterable(w_iterable) + assert slicelength >= 0 items = w_list.wrappeditems - + oldsize = len(items) + len2 = len(sequence2) if step == 1: # Support list resizing for non-extended slices - delta = len2 - slicelength - if delta >= 0: + delta = slicelength - len2 + if delta < 0: + delta = -delta newsize = oldsize + delta # XXX support this in rlist! items += [None] * delta @@ -271,9 +279,10 @@ while i >= lim: items[i] = items[i-delta] i -= 1 + elif start >= 0: + del items[start:start+delta] else: - # shrinking requires the careful memory management of _del_slice() - _del_slice(w_list, start, start-delta) + assert delta==0 elif len2 != slicelength: # No resize for extended slices raise OperationError(space.w_ValueError, space.wrap("attempt to " "assign sequence of size %d to extended slice of size %d" % @@ -290,14 +299,13 @@ items[start] = sequence2[i] start -= step i -= 1 - return space.w_None + return else: # Make a shallow copy to more easily handle the reversal case sequence2 = list(sequence2) for i in range(len2): items[start] = sequence2[i] start += step - return space.w_None app = gateway.applevel(""" def listrepr(currently_in_repr, l): @@ -350,26 +358,6 @@ w_list.wrappeditems += space.unpackiterable(w_any) return space.w_None -def _del_slice(w_list, ilow, ihigh): - """ similar to the deletion part of list_ass_slice in CPython """ - items = w_list.wrappeditems - n = len(items) - if ilow < 0: - ilow = 0 - elif ilow > n: - ilow = n - if ihigh < ilow: - ihigh = ilow - elif ihigh > n: - ihigh = n - # keep a reference to the objects to be removed, - # preventing side effects during destruction - recycle = items[ilow:ihigh] - del items[ilow:ihigh] - # now we can destruct recycle safely, regardless of - # side-effects to the list - del recycle[:] - # note that the default value will come back wrapped!!! def list_pop__List_ANY(space, w_list, w_idx=-1): items = w_list.wrappeditems Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Sat Oct 11 19:01:14 2008 @@ -764,33 +764,6 @@ else: return ObjSpace.call_method(self, w_obj, methname, *arg_w) - # support for the deprecated __getslice__, __setslice__, __delslice__ - - def getslice(self, w_obj, w_start, w_stop): - w_descr = self.lookup(w_obj, '__getslice__') - if w_descr is not None: - w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) - return self.get_and_call_function(w_descr, w_obj, w_start, w_stop) - else: - return ObjSpace.getslice(self, w_obj, w_start, w_stop) - - def setslice(self, w_obj, w_start, w_stop, w_sequence): - w_descr = self.lookup(w_obj, '__setslice__') - if w_descr is not None: - w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) - self.get_and_call_function(w_descr, w_obj, w_start, w_stop, - w_sequence) - else: - ObjSpace.setslice(self, w_obj, w_start, w_stop, w_sequence) - - def delslice(self, w_obj, w_start, w_stop): - w_descr = self.lookup(w_obj, '__delslice__') - if w_descr is not None: - w_start, w_stop = old_slice_range(self, w_obj, w_start, w_stop) - self.get_and_call_function(w_descr, w_obj, w_start, w_stop) - else: - ObjSpace.delslice(self, w_obj, w_start, w_stop) - def raise_key_error(self, w_key): e = self.call_function(self.w_KeyError, w_key) raise OperationError(self.w_KeyError, e) @@ -820,32 +793,3 @@ del mm pow.extras['defaults'] = (None,) - - -# what is the maximum value slices can get on CPython? -# we need to stick to that value, because fake.py etc. -class Temp: - def __getslice__(self, i, j): - return j -slice_max = Temp()[:] -del Temp - - -def old_slice_range(space, w_obj, w_start, w_stop): - """Only for backward compatibility for __getslice__()&co methods.""" - if space.is_w(w_start, space.w_None): - w_start = space.wrap(0) - else: - w_start = space.wrap(space.getindex_w(w_start, None)) - if space.is_true(space.lt(w_start, space.wrap(0))): - w_start = space.add(w_start, space.len(w_obj)) - # NB. the language ref is inconsistent with the new-style class - # behavior when w_obj doesn't implement __len__(), so we just - # ignore this case. - if space.is_w(w_stop, space.w_None): - w_stop = space.wrap(slice_max) - else: - w_stop = space.wrap(space.getindex_w(w_stop, None)) - if space.is_true(space.lt(w_stop, space.wrap(0))): - w_stop = space.add(w_stop, space.len(w_obj)) - return w_start, w_stop Modified: pypy/trunk/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/rangeobject.py (original) +++ pypy/trunk/pypy/objspace/std/rangeobject.py Sat Oct 11 19:01:14 2008 @@ -1,7 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std import listtype from pypy.objspace.std import iterobject @@ -100,6 +100,17 @@ rangestep = w_rangelist.step * step return W_RangeListObject(rangestart, rangestep, slicelength) +def getslice__RangeList_ANY_ANY(space, w_rangelist, w_start, w_stop): + if w_rangelist.w_list is not None: + return space.getslice(w_rangelist.w_list, w_start, w_stop) + length = w_rangelist.length + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + slicelength = stop - start + assert slicelength >= 0 + rangestart = w_rangelist.getitem_unchecked(start) + rangestep = w_rangelist.step + return W_RangeListObject(rangestart, rangestep, slicelength) + def iter__RangeList(space, w_rangelist): return W_RangeIterObject(w_rangelist) Modified: pypy/trunk/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeobject.py Sat Oct 11 19:01:14 2008 @@ -2,7 +2,7 @@ from pypy.interpreter import gateway from pypy.rlib.objectmodel import we_are_translated from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.noneobject import W_NoneObject @@ -693,6 +693,15 @@ return W_RopeObject.EMPTY return W_RopeObject(rope.getslice(node, start, stop, step, sl)) +def getslice__Rope_ANY_ANY(space, w_str, w_start, w_stop): + node = w_str._node + length = node.length() + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + sl = stop - start + if sl == 0: + return W_RopeObject.EMPTY + return W_RopeObject(rope.getslice(node, start, stop, 1, sl)) + def mul_string_times(space, w_str, w_times): try: mul = space.getindex_w(w_times, space.w_OverflowError) Modified: pypy/trunk/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeunicodeobject.py Sat Oct 11 19:01:14 2008 @@ -5,7 +5,7 @@ from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib import rope -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.objspace.std.tupleobject import W_TupleObject from pypy.rlib.rarithmetic import intmask, ovfcheck @@ -287,6 +287,15 @@ return W_RopeUnicodeObject.EMPTY return W_RopeUnicodeObject(rope.getslice(node, start, stop, step, sl)) +def getslice__RopeUnicode_ANY_ANY(space, w_uni, w_start, w_stop): + node = w_uni._node + length = node.length() + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + sl = stop - start + if sl == 0: + return W_RopeUnicodeObject.EMPTY + return W_RopeUnicodeObject(rope.getslice(node, start, stop, 1, sl)) + def mul__RopeUnicode_ANY(space, w_uni, w_times): try: times = space.getindex_w(w_times, space.w_OverflowError) Modified: pypy/trunk/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/sliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/sliceobject.py Sat Oct 11 19:01:14 2008 @@ -79,6 +79,19 @@ registerimplementation(W_SliceObject) +def normalize_simple_slice(space, length, w_start, w_stop): + """Helper for the {get,set,del}slice multimethod implementations.""" + start = space.int_w(w_start) + stop = space.int_w(w_stop) + if start < 0: + start = 0 + if stop > length: + stop = length + if stop < start: + stop = start + return start, stop + + repr__Slice = gateway.applevel(""" def repr__Slice(aslice): return 'slice(%r, %r, %r)' % (aslice.start, aslice.stop, aslice.step) Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Sat Oct 11 19:01:14 2008 @@ -5,7 +5,7 @@ from pypy.rlib.rarithmetic import ovfcheck, _hash_string from pypy.rlib.objectmodel import we_are_translated from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.noneobject import W_NoneObject @@ -815,6 +815,14 @@ str = "".join([s[start + i*step] for i in range(sl)]) return wrapstr(space, str) +def getslice__String_ANY_ANY(space, w_str, w_start, w_stop): + s = w_str._value + start, stop = normalize_simple_slice(space, len(s), w_start, w_stop) + if start == stop: + return W_StringObject.EMPTY + else: + return sliced(space, s, start, stop) + def mul_string_times(space, w_str, w_times): try: mul = space.getindex_w(w_times, space.w_OverflowError) Modified: pypy/trunk/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/strsliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/strsliceobject.py Sat Oct 11 19:01:14 2008 @@ -1,7 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std import slicetype from pypy.objspace.std.inttype import wrapint @@ -194,6 +194,18 @@ str = "".join([s[start + i*step] for i in range(sl)]) return wrapstr(space, str) +def getslice__StringSlice_ANY_ANY(space, w_str, w_start, w_stop): + length = w_str.stop - w_str.start + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + sl = stop - start + if sl == 0: + return W_StringObject.EMPTY + else: + s = w_str.str + start = w_str.start + start + stop = w_str.start + stop + return W_StringSliceObject(s, start, stop) + def len__StringSlice(space, w_str): return space.wrap(w_str.stop - w_str.start) Modified: pypy/trunk/pypy/objspace/std/test/test_builtinshortcut.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_builtinshortcut.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_builtinshortcut.py Sat Oct 11 19:01:14 2008 @@ -1,5 +1,6 @@ from pypy.objspace.std.test import test_userobject from pypy.objspace.std.test import test_set +from pypy.objspace.std.test import test_stringobject WITH_BUILTINSHORTCUT = {'objspace.std.builtinshortcut': True} @@ -38,3 +39,8 @@ def setup_class(cls): from pypy import conftest cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) + +class AppTestString(test_stringobject.AppTestStringObject): + def setup_class(cls): + from pypy import conftest + cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) Modified: pypy/trunk/pypy/objspace/std/test/test_listmultiobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_listmultiobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_listmultiobject.py Sat Oct 11 19:01:14 2008 @@ -39,6 +39,15 @@ # These few here ^ would have failed before, but for good coverage, # all the list methods etc. should be tested also... + def test___getslice__(self): + skip("don't care for now") + + def test___setslice__(self): + skip("don't care for now") + + def test___delslice__(self): + skip("don't care for now") + class AppTest_ListMultiObject(BaseAppTest_ListMultiObject): def setup_class(cls): BaseAppTest_ListMultiObject.setup_class(cls) Modified: pypy/trunk/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_listobject.py Sat Oct 11 19:01:14 2008 @@ -754,3 +754,18 @@ A() while lst: keepalive.append(lst[:]) + + def test___getslice__(self): + l = [1,2,3,4] + res = l.__getslice__(0, 2) + assert res == [1, 2] + + def test___setslice__(self): + l = [1,2,3,4] + l.__setslice__(0, 2, [5, 6]) + assert l == [5, 6, 3, 4] + + def test___delslice__(self): + l = [1,2,3,4] + l.__delslice__(0, 2) + assert l == [3, 4] Modified: pypy/trunk/pypy/objspace/std/test/test_rangeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_rangeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_rangeobject.py Sat Oct 11 19:01:14 2008 @@ -29,6 +29,14 @@ def test_getitem_slice(self): result = [] r = range(1, 100, 2) + for i in r[10:15]: + result.append(i) + assert result == [21, 23, 25, 27, 29] + assert self.not_forced(r) + + def test_getitem_extended_slice(self): + result = [] + r = range(1, 100, 2) for i in r[40:30:-2]: result.append(i) assert result == [81, 77, 73, 69, 65] Modified: pypy/trunk/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_stringobject.py Sat Oct 11 19:01:14 2008 @@ -721,10 +721,24 @@ s = "a" * (2**16) raises(OverflowError, s.replace, "", s) + def test_getslice(self): + assert "foobar".__getslice__(4, 4321) == "ar" + s = "abc" + assert s[:] == "abc" + assert s[1:] == "bc" + assert s[:2] == "ab" + assert s[1:2] == "b" + assert s[-2:] == "bc" + assert s[:-1] == "ab" + assert s[-2:2] == "b" + assert s[1:-1] == "b" + assert s[-2:-1] == "b" + def test_no_len_on_str_iter(self): iterable = "hello" raises(TypeError, len, iter(iterable)) + class AppTestPrebuilt(AppTestStringObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True}) Modified: pypy/trunk/pypy/objspace/std/test/test_strsliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_strsliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_strsliceobject.py Sat Oct 11 19:01:14 2008 @@ -133,3 +133,16 @@ assert s.count("X") == 100 assert s.count("Y") == 100 assert self.not_forced(s) + + def test_extended_slice(self): + import __pypy__ + def slice1(s): return (s*3)[len(s):-len(s)] + s = slice1('0123456789' * 20) + assert len(s) == 200 + assert self.not_forced(s) + t = s[::-1] + assert t == '9876543210' * 20 + assert not self.not_forced(t) + u = s[slice(10, 20)] + assert self.not_forced(u) + assert u == '0123456789' Modified: pypy/trunk/pypy/objspace/std/test/test_tupleobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_tupleobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_tupleobject.py Sat Oct 11 19:01:14 2008 @@ -318,3 +318,5 @@ assert repr(()) == '()' assert repr((1,2,3)) == '(1, 2, 3)' + def test_getslice(self): + assert ('a', 'b', 'c').__getslice__(-17, 2) == ('a', 'b') Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Sat Oct 11 19:01:14 2008 @@ -636,6 +636,19 @@ assert unicode(Y()).__class__ is X + def test_getslice(self): + assert u'123456'.__getslice__(1, 5) == u'2345' + s = u"abc" + assert s[:] == "abc" + assert s[1:] == "bc" + assert s[:2] == "ab" + assert s[1:2] == "b" + assert s[-2:] == "bc" + assert s[:-1] == "ab" + assert s[-2:2] == "b" + assert s[1:-1] == "b" + assert s[-2:-1] == "b" + def test_no_len_on_str_iter(self): iterable = u"hello" raises(TypeError, len, iter(iterable)) Modified: pypy/trunk/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/tupleobject.py (original) +++ pypy/trunk/pypy/objspace/std/tupleobject.py Sat Oct 11 19:01:14 2008 @@ -1,7 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.inttype import wrapint from pypy.rlib.rarithmetic import intmask -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.interpreter import gateway from pypy.rlib.debug import make_sure_not_resized @@ -53,6 +53,11 @@ start += step return W_TupleObject(subitems) +def getslice__Tuple_ANY_ANY(space, w_tuple, w_start, w_stop): + length = len(w_tuple.wrappeditems) + start, stop = normalize_simple_slice(space, length, w_start, w_stop) + return W_TupleObject(w_tuple.wrappeditems[start:stop]) + def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): Modified: pypy/trunk/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/unicodeobject.py Sat Oct 11 19:01:14 2008 @@ -3,7 +3,7 @@ from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject -from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std import slicetype from pypy.objspace.std.tupleobject import W_TupleObject from pypy.rlib.rarithmetic import intmask, ovfcheck @@ -247,6 +247,11 @@ r = u"".join([uni[start + i*step] for i in range(sl)]) return W_UnicodeObject(r) +def getslice__Unicode_ANY_ANY(space, w_uni, w_start, w_stop): + uni = w_uni._value + start, stop = normalize_simple_slice(space, len(uni), w_start, w_stop) + return W_UnicodeObject(uni[start:stop]) + def mul__Unicode_ANY(space, w_uni, w_times): try: times = space.getindex_w(w_times, space.w_OverflowError) Modified: pypy/trunk/pypy/objspace/thunk.py ============================================================================== --- pypy/trunk/pypy/objspace/thunk.py (original) +++ pypy/trunk/pypy/objspace/thunk.py Sat Oct 11 19:01:14 2008 @@ -193,6 +193,13 @@ w2 = force(space, w2) w3 = force(space, w3) return parentfn(w1, w2, w3, *extra) + elif nb_args == 4: + def proxy(w1, w2, w3, w4, *extra): + w1 = force(space, w1) + w2 = force(space, w2) + w3 = force(space, w3) + w4 = force(space, w4) + return parentfn(w1, w2, w3, w4, *extra) else: raise NotImplementedError("operation %r has arity %d" % (opname, nb_args)) Modified: pypy/trunk/pypy/rpython/lltypesystem/rlist.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rlist.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rlist.py Sat Oct 11 19:01:14 2008 @@ -7,9 +7,6 @@ AbstractFixedSizeListRepr, AbstractListIteratorRepr, rtype_newlist, \ rtype_alloc_and_set, ll_setitem_nonneg, ADTIList, ADTIFixedList from pypy.rpython.rlist import dum_nocheck, dum_checkidx -from pypy.rpython.lltypesystem.rslice import SliceRepr -from pypy.rpython.lltypesystem.rslice import startstop_slice_repr, startonly_slice_repr -from pypy.rpython.lltypesystem.rslice import minusone_slice_repr from pypy.rpython.lltypesystem.lltype import \ GcForwardReference, Ptr, GcArray, GcStruct, \ Void, Signed, malloc, typeOf, Primitive, \ Deleted: /pypy/trunk/pypy/rpython/lltypesystem/rslice.py ============================================================================== --- /pypy/trunk/pypy/rpython/lltypesystem/rslice.py Sat Oct 11 19:01:14 2008 +++ (empty file) @@ -1,65 +0,0 @@ -from pypy.rpython.rslice import AbstractSliceRepr -from pypy.rpython.lltypesystem.lltype import \ - GcStruct, Signed, Ptr, Void, malloc, PyObject, nullptr -from pypy.tool.pairtype import pairtype -from pypy.rpython.robject import PyObjRepr, pyobj_repr -from pypy.rpython.rmodel import inputconst, PyObjPtr, IntegerRepr - -# ____________________________________________________________ -# -# Concrete implementation of RPython slice objects: -# -# - if stop is None, use only a Signed -# - if stop is not None: -# -# struct slice { -# Signed start; -# Signed stop; -# // step is always 1 -# } - -SLICE = GcStruct("slice", ("start", Signed), ("stop", Signed), - hints = {'immutable': True}) - -class SliceRepr(AbstractSliceRepr): - pass - -startstop_slice_repr = SliceRepr() -startstop_slice_repr.lowleveltype = Ptr(SLICE) -startonly_slice_repr = SliceRepr() -startonly_slice_repr.lowleveltype = Signed -minusone_slice_repr = SliceRepr() -minusone_slice_repr.lowleveltype = Void # only for [:-1] - -# ____________________________________________________________ - -def ll_newslice(start, stop): - s = malloc(SLICE) - s.start = start - s.stop = stop - return s - -# ____________________________________________________________ -# -# limited support for casting into PyObject - -# stuff like this should go into one file maybe - -class __extend__(pairtype(SliceRepr, PyObjRepr)): - def convert_from_to((r_from, r_to), v, llops): - null = inputconst(Ptr(PyObject), nullptr(PyObject)) - def pyint(v): - return llops.gencapicall('PyInt_FromLong', [v], resulttype=r_to) - v_step = v_start = v_stop = null - if r_from.lowleveltype is Signed: - v_start = pyint(v) - elif r_from.lowleveltype is Void: - v_stop = inputconst(r_to, -1) - else: - v_start = pyint(llops.genop('getfield', [v, inputconst(Void, 'start')], - resulttype=Signed)) - v_stop = pyint(llops.genop('getfield', [v, inputconst(Void, 'stop')], - resulttype=Signed)) - return llops.gencapicall('PySlice_New', - [v_start, v_stop, v_step], - resulttype = pyobj_repr) Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rstr.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rstr.py Sat Oct 11 19:01:14 2008 @@ -640,9 +640,7 @@ s1.copy_contents(s1, newstr, start, 0, lgt) return newstr - def ll_stringslice(s1, slice): - start = slice.start - stop = slice.stop + def ll_stringslice_startstop(s1, start, stop): if stop >= len(s1.chars): if start == 0: return s1 Modified: pypy/trunk/pypy/rpython/ootypesystem/rlist.py ============================================================================== --- pypy/trunk/pypy/rpython/ootypesystem/rlist.py (original) +++ pypy/trunk/pypy/rpython/ootypesystem/rlist.py Sat Oct 11 19:01:14 2008 @@ -5,8 +5,6 @@ from pypy.rpython.rmodel import inputconst, externalvsinternal from pypy.rpython.lltypesystem.lltype import Signed, Void from pypy.rpython.ootypesystem import ootype -from pypy.rpython.ootypesystem.rslice import SliceRepr, \ - startstop_slice_repr, startonly_slice_repr, minusone_slice_repr from pypy.rpython.ootypesystem import rstr Deleted: /pypy/trunk/pypy/rpython/ootypesystem/rslice.py ============================================================================== --- /pypy/trunk/pypy/rpython/ootypesystem/rslice.py Sat Oct 11 19:01:14 2008 +++ (empty file) @@ -1,24 +0,0 @@ -from pypy.rpython.rslice import AbstractSliceRepr -from pypy.rpython.lltypesystem.lltype import Void, Signed -from pypy.rpython.ootypesystem import ootype - -SLICE = ootype.Instance('Slice', ootype.ROOT, {'start': Signed, 'stop': Signed}) - -class SliceRepr(AbstractSliceRepr): - pass - -startstop_slice_repr = SliceRepr() -startstop_slice_repr.lowleveltype = SLICE -startonly_slice_repr = SliceRepr() -startonly_slice_repr.lowleveltype = Signed -minusone_slice_repr = SliceRepr() -minusone_slice_repr.lowleveltype = Void # only for [:-1] - -# ____________________________________________________________ - -def ll_newslice(start, stop): - s = ootype.new(SLICE) - s.start = start - s.stop = stop - return s - Modified: pypy/trunk/pypy/rpython/ootypesystem/rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/ootypesystem/rstr.py (original) +++ pypy/trunk/pypy/rpython/ootypesystem/rstr.py Sat Oct 11 19:01:14 2008 @@ -198,9 +198,7 @@ def ll_stringslice_startonly(s, start): return s.ll_substring(start, s.ll_strlen() - start) - def ll_stringslice(s, slice): - start = slice.start - stop = slice.stop + def ll_stringslice_startstop(s, start, stop): length = s.ll_strlen() if stop > length: stop = length Modified: pypy/trunk/pypy/rpython/rlist.py ============================================================================== --- pypy/trunk/pypy/rpython/rlist.py (original) +++ pypy/trunk/pypy/rpython/rlist.py Sat Oct 11 19:01:14 2008 @@ -3,7 +3,6 @@ from pypy.annotation import model as annmodel from pypy.rpython.error import TyperError from pypy.rpython.rmodel import Repr, IteratorRepr, IntegerRepr, inputconst -from pypy.rpython.rslice import AbstractSliceRepr 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 @@ -371,24 +370,14 @@ if r_lst1.item_repr.lowleveltype not in (Char, UniChar): raise TyperError('"lst += string" only supported with a list ' 'of chars or unichars') - rs = r_lst1.rtyper.type_system.rslice string_repr = r_lst1.rtyper.type_system.rstr.string_repr + v_lst1 = hop.inputarg(r_lst1, arg=0) + v_str2 = hop.inputarg(string_repr, arg=3) + kind, vlist = hop.decompose_slice_args() c_strlen = hop.inputconst(Void, string_repr.ll.ll_strlen) c_stritem = hop.inputconst(Void, string_repr.ll.ll_stritem_nonneg) - r_slic = hop.args_r[2] - v_lst1, v_str2, v_slice = hop.inputargs(r_lst1, string_repr, r_slic) - if r_slic == rs.startonly_slice_repr: - hop.gendirectcall(ll_extend_with_str_slice_startonly, - v_lst1, v_str2, c_strlen, c_stritem, v_slice) - elif r_slic == rs.startstop_slice_repr: - hop.gendirectcall(ll_extend_with_str_slice, - v_lst1, v_str2, c_strlen, c_stritem, v_slice) - elif r_slic == rs.minusone_slice_repr: - hop.gendirectcall(ll_extend_with_str_slice_minusone, - v_lst1, v_str2, c_strlen, c_stritem) - else: - raise TyperError('lst += str[:] does not support slices with %r' % - (r_slic,)) + ll_fn = globals()['ll_extend_with_str_slice_%s' % kind] + hop.gendirectcall(ll_fn, v_lst1, v_str2, c_strlen, c_stritem, *vlist) return v_lst1 class __extend__(pairtype(AbstractListRepr, AbstractCharRepr)): @@ -403,47 +392,30 @@ return v_lst1 -class __extend__(pairtype(AbstractBaseListRepr, AbstractSliceRepr)): +class __extend__(AbstractBaseListRepr): - def rtype_getitem((r_lst, r_slic), hop): - rs = r_lst.rtyper.type_system.rslice + def rtype_getslice(r_lst, hop): cRESLIST = hop.inputconst(Void, hop.r_result.LIST) - if r_slic == rs.startonly_slice_repr: - v_lst, v_start = hop.inputargs(r_lst, rs.startonly_slice_repr) - return hop.gendirectcall(ll_listslice_startonly, cRESLIST, v_lst, v_start) - if r_slic == rs.startstop_slice_repr: - v_lst, v_slice = hop.inputargs(r_lst, rs.startstop_slice_repr) - return hop.gendirectcall(ll_listslice, cRESLIST, v_lst, v_slice) - if r_slic == rs.minusone_slice_repr: - v_lst, v_ignored = hop.inputargs(r_lst, rs.minusone_slice_repr) - return hop.gendirectcall(ll_listslice_minusone, cRESLIST, v_lst) - raise TyperError('getitem does not support slices with %r' % (r_slic,)) - - def rtype_setitem((r_lst, r_slic), hop): - #if r_slic == startonly_slice_repr: - # not implemented - rs = r_lst.rtyper.type_system.rslice - if r_slic == rs.startstop_slice_repr: - v_lst, v_slice, v_lst2 = hop.inputargs(r_lst, rs.startstop_slice_repr, - hop.args_r[2]) - hop.gendirectcall(ll_listsetslice, v_lst, v_slice, v_lst2) - return - raise TyperError('setitem does not support slices with %r' % (r_slic,)) - - -class __extend__(pairtype(AbstractListRepr, AbstractSliceRepr)): - - def rtype_delitem((r_lst, r_slic), hop): - rs = r_lst.rtyper.type_system.rslice - if r_slic == rs.startonly_slice_repr: - v_lst, v_start = hop.inputargs(r_lst, rs.startonly_slice_repr) - hop.gendirectcall(ll_listdelslice_startonly, v_lst, v_start) - return - if r_slic == rs.startstop_slice_repr: - v_lst, v_slice = hop.inputargs(r_lst, rs.startstop_slice_repr) - hop.gendirectcall(ll_listdelslice, v_lst, v_slice) - return - raise TyperError('delitem does not support slices with %r' % (r_slic,)) + v_lst = hop.inputarg(r_lst, arg=0) + kind, vlist = hop.decompose_slice_args() + ll_listslice = globals()['ll_listslice_%s' % kind] + return hop.gendirectcall(ll_listslice, cRESLIST, v_lst, *vlist) + + def rtype_setslice(r_lst, hop): + v_lst = hop.inputarg(r_lst, arg=0) + kind, vlist = hop.decompose_slice_args() + if kind != 'startstop': + raise TyperError('list.setitem does not support %r slices' % ( + kind,)) + v_start, v_stop = vlist + v_lst2 = hop.inputarg(hop.args_r[3], arg=3) + hop.gendirectcall(ll_listsetslice, v_lst, v_start, v_stop, v_lst2) + + def rtype_delslice(r_lst, hop): + v_lst = hop.inputarg(r_lst, arg=0) + kind, vlist = hop.decompose_slice_args() + ll_listdelslice = globals()['ll_listdelslice_%s' % kind] + return hop.gendirectcall(ll_listdelslice, v_lst, *vlist) # ____________________________________________________________ @@ -793,9 +765,8 @@ i += 1 j += 1 -def ll_extend_with_str_slice(lst, s, getstrlen, getstritem, slice): - start = slice.start - stop = slice.stop +def ll_extend_with_str_slice_startstop(lst, s, getstrlen, getstritem, + start, stop): len1 = lst.ll_length() len2 = getstrlen(s) ll_assert(start >= 0, "unexpectedly negative str slice start") @@ -868,9 +839,7 @@ j += 1 return l -def ll_listslice(RESLIST, l1, slice): - start = slice.start - stop = slice.stop +def ll_listslice_startstop(RESLIST, l1, start, stop): length = l1.ll_length() ll_assert(start >= 0, "unexpectedly negative list slice start") ll_assert(start <= length, "list slice start larger than list length") @@ -909,9 +878,7 @@ j -= 1 l._ll_resize_le(newlength) -def ll_listdelslice(l, slice): - start = slice.start - stop = slice.stop +def ll_listdelslice_startstop(l, start, stop): length = l.ll_length() ll_assert(start >= 0, "del l[start:x] with unexpectedly negative start") ll_assert(start <= length, "del l[start:x] with start > len(l)") @@ -933,12 +900,11 @@ j -= 1 l._ll_resize_le(newlength) -def ll_listsetslice(l1, slice, l2): +def ll_listsetslice(l1, start, stop, l2): count = l2.ll_length() - start = slice.start ll_assert(start >= 0, "l[start:x] = l with unexpectedly negative start") ll_assert(start <= l1.ll_length(), "l[start:x] = l with start > len(l)") - ll_assert(count == slice.stop - start, + ll_assert(count == stop - start, "setslice cannot resize lists in RPython") # XXX but it should be easy enough to support, soon j = start Deleted: /pypy/trunk/pypy/rpython/rslice.py ============================================================================== --- /pypy/trunk/pypy/rpython/rslice.py Sat Oct 11 19:01:14 2008 +++ (empty file) @@ -1,61 +0,0 @@ -from pypy.rpython.rmodel import Repr -from pypy.rpython.lltypesystem.lltype import Signed, Void -from pypy.objspace.flow.model import Constant -from pypy.annotation import model as annmodel -from pypy.rpython.error import TyperError - -class AbstractSliceRepr(Repr): - pass - - -def select_slice_repr(self): - # Select which one of the three prebuilt reprs to use. - # Return a name. - if not self.step.is_constant() or self.step.const not in (None, 1): - raise TyperError("only supports slices with step 1") - if (self.start.is_constant() and self.start.const in (None, 0) and - self.stop.is_constant() and self.stop.const == -1): - return "minusone_slice_repr" # [:-1] - if isinstance(self.start, annmodel.SomeInteger): - if not self.start.nonneg: - raise TyperError("slice start must be proved non-negative") - if isinstance(self.stop, annmodel.SomeInteger): - if not self.stop.nonneg: - raise TyperError("slice stop must be proved non-negative") - if self.stop.is_constant() and self.stop.const is None: - return "startonly_slice_repr" - else: - return "startstop_slice_repr" - -class __extend__(annmodel.SomeSlice): - def rtyper_makerepr(self, rtyper): - return getattr(rtyper.type_system.rslice, select_slice_repr(self)) - - def rtyper_makekey(self): - return self.__class__, select_slice_repr(self) - - -def rtype_newslice(hop): - sig = [] - for s in hop.args_s: - if s.is_constant() and s.const is None: - sig.append(Void) - else: - sig.append(Signed) - v_start, v_stop, v_step = hop.inputargs(*sig) - assert isinstance(v_step, Constant) and v_step.value in (None, 1) - if isinstance(v_start, Constant) and v_start.value is None: - v_start = hop.inputconst(Signed, 0) - if (isinstance(v_start, Constant) and v_start.value == 0 and - isinstance(v_stop, Constant) and v_stop.value == -1): - # [:-1] slice - return hop.inputconst(Void, slice(None,-1)) - if isinstance(v_stop, Constant) and v_stop.value is None: - # start-only slice - # NB. cannot just return v_start in case it is a constant - return hop.genop('same_as', [v_start], - resulttype=hop.rtyper.type_system.rslice.startonly_slice_repr) - else: - # start-stop slice - return hop.gendirectcall(hop.rtyper.type_system.rslice.ll_newslice, - v_start, v_stop) Modified: pypy/trunk/pypy/rpython/rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/rstr.py (original) +++ pypy/trunk/pypy/rpython/rstr.py Sat Oct 11 19:01:14 2008 @@ -5,7 +5,6 @@ from pypy.rpython.rmodel import IntegerRepr, IteratorRepr from pypy.rpython.rmodel import inputconst, Repr from pypy.rpython.rtuple import AbstractTupleRepr -from pypy.rpython.rslice import AbstractSliceRepr from pypy.rpython import rint from pypy.rpython.lltypesystem.lltype import Signed, Bool, Void, UniChar,\ cast_primitive @@ -331,22 +330,14 @@ rtype_getitem_idx_key = rtype_getitem_idx -class __extend__(pairtype(AbstractStringRepr, AbstractSliceRepr)): +class __extend__(AbstractStringRepr): - def rtype_getitem((r_str, r_slic), hop): + def rtype_getslice(r_str, hop): string_repr = r_str.repr - rslice = hop.rtyper.type_system.rslice - - if r_slic == rslice.startonly_slice_repr: - v_str, v_start = hop.inputargs(string_repr, rslice.startonly_slice_repr) - return hop.gendirectcall(r_str.ll.ll_stringslice_startonly, v_str, v_start) - if r_slic == rslice.startstop_slice_repr: - v_str, v_slice = hop.inputargs(string_repr, rslice.startstop_slice_repr) - return hop.gendirectcall(r_str.ll.ll_stringslice, v_str, v_slice) - if r_slic == rslice.minusone_slice_repr: - v_str, v_ignored = hop.inputargs(string_repr, rslice.minusone_slice_repr) - return hop.gendirectcall(r_str.ll.ll_stringslice_minusone, v_str) - raise TyperError(r_slic) + v_str = hop.inputarg(string_repr, arg=0) + kind, vlist = hop.decompose_slice_args() + ll_fn = getattr(r_str.ll, 'll_stringslice_%s' % (kind,)) + return hop.gendirectcall(ll_fn, v_str, *vlist) class __extend__(pairtype(AbstractStringRepr, AbstractStringRepr)): def rtype_add((r_str1, r_str2), hop): Modified: pypy/trunk/pypy/rpython/rtuple.py ============================================================================== --- pypy/trunk/pypy/rpython/rtuple.py (original) +++ pypy/trunk/pypy/rpython/rtuple.py Sat Oct 11 19:01:14 2008 @@ -6,7 +6,6 @@ from pypy.rpython.rmodel import Repr, IntegerRepr, inputconst from pypy.rpython.rmodel import IteratorRepr from pypy.rpython.rmodel import externalvsinternal -from pypy.rpython.rslice import AbstractSliceRepr from pypy.rpython.lltypesystem.lltype import Void, Signed, Bool from pypy.rlib.rarithmetic import intmask from pypy.rlib.unroll import unrolling_iterable @@ -242,15 +241,19 @@ index = v_index.value return r_tup.getitem(hop.llops, v_tuple, index) -class __extend__(pairtype(AbstractTupleRepr, AbstractSliceRepr)): +class __extend__(AbstractTupleRepr): - def rtype_getitem((r_tup, r_slice), hop): - v_tup = hop.inputarg(r_tup, arg=0) - s_slice = hop.args_s[1] - start, stop, step = s_slice.constant_indices() - indices = range(len(r_tup.items_r))[start:stop:step] + def rtype_getslice(r_tup, hop): + s_start = hop.args_s[1] + s_stop = hop.args_s[2] + assert s_start.is_immutable_constant(),"tuple slicing: needs constants" + assert s_stop.is_immutable_constant(), "tuple slicing: needs constants" + start = s_start.const + stop = s_stop.const + indices = range(len(r_tup.items_r))[start:stop] assert len(indices) == len(hop.r_result.items_r) + v_tup = hop.inputarg(r_tup, arg=0) items_v = [r_tup.getitem_internal(hop.llops, v_tup, i) for i in indices] return hop.r_result.newtuple(hop.llops, hop.r_result, items_v) Modified: pypy/trunk/pypy/rpython/rtyper.py ============================================================================== --- pypy/trunk/pypy/rpython/rtyper.py (original) +++ pypy/trunk/pypy/rpython/rtyper.py Sat Oct 11 19:01:14 2008 @@ -578,7 +578,7 @@ def translate_op_extend_with_str_slice(self, hop): r_arg1 = hop.args_r[0] - r_arg2 = hop.args_r[1] + r_arg2 = hop.args_r[3] return pair(r_arg1, r_arg2).rtype_extend_with_str_slice(hop) def translate_op_extend_with_char_count(self, hop): @@ -589,9 +589,6 @@ def translate_op_newtuple(self, hop): return self.type_system.rtuple.rtype_newtuple(hop) - def translate_op_newslice(self, hop): - return rslice.rtype_newslice(hop) - def translate_op_instantiate1(self, hop): from pypy.rpython.lltypesystem import rclass if not isinstance(hop.s_result, annmodel.SomeInstance): @@ -811,6 +808,32 @@ return # ignored for high-level ops before the last one in the block self.llops.llop_raising_exceptions = "removed" + def decompose_slice_args(self): + # Select which kind of slicing is needed. We support: + # * [start:] + # * [start:stop] + # * [:-1] + s_start = self.args_s[1] + s_stop = self.args_s[2] + if (s_start.is_constant() and s_start.const in (None, 0) and + s_stop.is_constant() and s_stop.const == -1): + return "minusone", [] + if isinstance(s_start, annmodel.SomeInteger): + if not s_start.nonneg: + raise TyperError("slice start must be proved non-negative") + if isinstance(s_stop, annmodel.SomeInteger): + if not s_stop.nonneg: + raise TyperError("slice stop must be proved non-negative") + if s_start.is_constant() and s_start.const is None: + v_start = inputconst(Signed, 0) + else: + v_start = self.inputarg(Signed, arg=1) + if s_stop.is_constant() and s_stop.const is None: + return "startonly", [v_start] + else: + v_stop = self.inputarg(Signed, arg=2) + return "startstop", [v_start, v_stop] + # ____________________________________________________________ class LowLevelOpList(list): @@ -935,7 +958,7 @@ # and the rtyper_chooserepr() methods from pypy.rpython import robject from pypy.rpython import rint, rbool, rfloat -from pypy.rpython import rslice, rrange +from pypy.rpython import rrange from pypy.rpython import rstr, rdict, rlist from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase from pypy.rpython import rexternalobj Modified: pypy/trunk/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rlist.py (original) +++ pypy/trunk/pypy/rpython/test/test_rlist.py Sat Oct 11 19:01:14 2008 @@ -7,7 +7,6 @@ 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.ootypesystem import rlist as oo_rlist -from pypy.rpython.lltypesystem.rslice import ll_newslice from pypy.rpython.rint import signed_repr from pypy.translator.translator import TranslationContext from pypy.objspace.flow.model import Constant, Variable @@ -58,8 +57,8 @@ self.check_list(ll_listslice_startonly(LIST, l, 4), []) for start in range(5): for stop in range(start, 8): - s = ll_newslice(start, stop) - self.check_list(ll_listslice(LIST, l, s), [42, 43, 44, 45][start:stop]) + self.check_list(ll_listslice_startstop(LIST, l, start, stop), + [42, 43, 44, 45][start:stop]) def test_rlist_setslice(self): n = 100 @@ -72,9 +71,8 @@ expected[i] = n ll_setitem(l2, i, n) n += 1 - s = ll_newslice(start, stop) - l2 = ll_listslice(typeOf(l2).TO, l2, s) - ll_listsetslice(l1, s, l2) + l2 = ll_listslice_startstop(typeOf(l2).TO, l2, start, stop) + ll_listsetslice(l1, start, stop, l2) self.check_list(l1, expected) @@ -129,8 +127,7 @@ for start in range(5): for stop in range(start, 8): l = self.sample_list() - s = ll_newslice(start, stop) - ll_listdelslice(l, s) + ll_listdelslice_startstop(l, start, stop) expected = [42, 43, 44, 45] del expected[start:stop] self.check_list(l, expected) @@ -327,6 +324,19 @@ assert self.ll_to_list(res.item1) == [6, 7, 8] assert self.ll_to_list(res.item2) == [8, 9] + def test_getslice_not_constant_folded(self): + l = list('abcdef') + + def dummyfn(): + result = [] + for i in range(3): + l2 = l[2:] + result.append(l2.pop()) + return result + + res = self.interpret(dummyfn, []) + assert self.ll_to_list(res) == ['f', 'f', 'f'] + def test_set_del_item(self): def dummyfn(): l = [5, 6, 7] @@ -380,6 +390,25 @@ assert res.item2 == 8 assert res.item3 == 7 + def test_delslice(self): + def dummyfn(): + l = [10, 9, 8, 7] + del l[:2] + return len(l), l[0], l[1] + res = self.interpret(dummyfn, ()) + assert res.item0 == 2 + assert res.item1 == 8 + assert res.item2 == 7 + + def dummyfn(): + l = [10, 9, 8, 7] + del l[2:] + return len(l), l[0], l[1] + res = self.interpret(dummyfn, ()) + assert res.item0 == 2 + assert res.item1 == 10 + assert res.item2 == 9 + def test_bltn_list(self): def dummyfn(): l1 = [42] Modified: pypy/trunk/pypy/rpython/test/test_rtyper.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rtyper.py (original) +++ pypy/trunk/pypy/rpython/test/test_rtyper.py Sat Oct 11 19:01:14 2008 @@ -27,35 +27,6 @@ key2 = rtyper.makekey(stup2) assert key1 != key2 -def test_slice_reprkeys(): - one = annmodel.SomeInteger(nonneg=True) - one.const = 1 - three = annmodel.SomeInteger(nonneg=True) - three.const = 3 - minusone = annmodel.SomeInteger() - minusone.const = -1 - none = annmodel.s_None - - startonly = annmodel.SomeSlice(one, none, none) - startonly2 = annmodel.SomeSlice(one, none, one) - startonly3 = annmodel.SomeSlice(three, none, one) - - startstop = annmodel.SomeSlice(one, one, none) - startstop2 = annmodel.SomeSlice(one, one, one) - startstop3 = annmodel.SomeSlice(one, three, none) - - minusone_slice = annmodel.SomeSlice(none, minusone, none) - minusone_slice2 = annmodel.SomeSlice(none, minusone, one) - - assert startonly.rtyper_makekey() == startonly2.rtyper_makekey() == startonly3.rtyper_makekey() - assert startstop.rtyper_makekey() == startstop2.rtyper_makekey() == startstop3.rtyper_makekey() - assert minusone_slice.rtyper_makekey() == minusone_slice2.rtyper_makekey() - - assert startonly.rtyper_makekey() != startstop.rtyper_makekey() - assert startonly.rtyper_makekey() != minusone_slice.rtyper_makekey() - assert minusone_slice.rtyper_makekey() != startstop.rtyper_makekey() - - def test_simple(): def dummyfn(x): return x+1 Modified: pypy/trunk/pypy/translator/simplify.py ============================================================================== --- pypy/trunk/pypy/translator/simplify.py (original) +++ pypy/trunk/pypy/translator/simplify.py Sat Oct 11 19:01:14 2008 @@ -483,7 +483,7 @@ # (they have no side effects, at least in R-Python) CanRemove = {} for _op in ''' - newtuple newlist newdict newslice is_true + newtuple newlist newdict is_true is_ id type issubtype repr str len hash getattr getitem pos neg nonzero abs hex oct ord invert add sub mul truediv floordiv div mod divmod pow lshift rshift and_ or_ Modified: pypy/trunk/pypy/translator/test/test_simplify.py ============================================================================== --- pypy/trunk/pypy/translator/test/test_simplify.py (original) +++ pypy/trunk/pypy/translator/test/test_simplify.py Sat Oct 11 19:01:14 2008 @@ -200,7 +200,7 @@ transform_dead_op_vars(graph, t) interp = LLInterpreter(t.rtyper) e = py.test.raises(LLException, 'interp.eval_graph(graph, [])') - assert 'ValueError' in str(e) + assert 'ValueError' in str(e.value) class TestDetectListComprehension: def check(self, f1, expected): Modified: pypy/trunk/pypy/translator/transform.py ============================================================================== --- pypy/trunk/pypy/translator/transform.py (original) +++ pypy/trunk/pypy/translator/transform.py Sat Oct 11 19:01:14 2008 @@ -57,10 +57,10 @@ # lst += string[x:y] # --> -# b = getitem(string, slice) +# b = getslice(string, x, y) # c = inplace_add(lst, b) # --> -# c = extend_with_str_slice(lst, string, slice) +# c = extend_with_str_slice(lst, x, y, string) def transform_extend_with_str_slice(self, block_subset): """Transforms lst += string[x:y] to extend_with_str_slice""" @@ -68,16 +68,15 @@ slice_sources = {} # maps b to [string, slice] in the above notation for i in range(len(block.operations)): op = block.operations[i] - if (op.opname == 'getitem' and - self.gettype(op.args[0]) is str and - self.gettype(op.args[1]) is slice): + if (op.opname == 'getslice' and + self.gettype(op.args[0]) is str): slice_sources[op.result] = op.args elif (op.opname == 'inplace_add' and op.args[1] in slice_sources and self.gettype(op.args[0]) is list): - v_string, v_slice = slice_sources[op.args[1]] + v_string, v_x, v_y = slice_sources[op.args[1]] new_op = SpaceOperation('extend_with_str_slice', - [op.args[0], v_string, v_slice], + [op.args[0], v_x, v_y, v_string], op.result) block.operations[i] = new_op @@ -112,30 +111,6 @@ op.result) block.operations[i] = new_op -# a[b:c] -# --> -# d = newslice(b, c, None) -# e = getitem(a, d) -# --> -# e = getslice(a, b, c) - -##def transform_slice(self, block_subset): -- not used any more -- -## """Transforms a[b:c] to getslice(a, b, c).""" -## for block in block_subset: -## operations = block.operations[:] -## n_op = len(operations) -## for i in range(0, n_op-1): -## op1 = operations[i] -## op2 = operations[i+1] -## if (op1.opname == 'newslice' and -## self.gettype(op1.args[2]) is types.NoneType and -## op2.opname == 'getitem' and -## op1.result is op2.args[1]): -## new_op = SpaceOperation('getslice', -## (op2.args[0], op1.args[0], op1.args[1]), -## op2.result) -## block.operations[i+1:i+2] = [new_op] - def transform_dead_op_vars(self, block_subset): # we redo the same simplification from simplify.py, From arigo at codespeak.net Sat Oct 11 18:37:31 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 18:37:31 +0200 (CEST) Subject: [pypy-svn] r58997 - pypy/trunk/pypy/objspace/std/test Message-ID: <20081011163731.1FF5516A27C@codespeak.net> Author: arigo Date: Sat Oct 11 18:37:29 2008 New Revision: 58997 Modified: pypy/trunk/pypy/objspace/std/test/test_dictmultiobject.py Log: Remove this test, which is now out-of-date and has an up-to-date duplicate. Modified: pypy/trunk/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_dictmultiobject.py Sat Oct 11 18:37:29 2008 @@ -14,20 +14,6 @@ def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withmultidict": True}) - def test_len_iter(self): - d = {1: 2, 3: 4} - i = iter(d) - assert len(i) == 2 - x = i.next() - assert len(i) == 1 - y = i.next() - assert len(i) == 0 - l = [x, y] - l.sort() - assert l == [1, 3] - raises(StopIteration, i.next) - raises(StopIteration, i.next) - def test_emptydict_unhashable(self): raises(TypeError, "{}[['x']]") From xoraxax at codespeak.net Sat Oct 11 19:18:45 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 11 Oct 2008 19:18:45 +0200 (CEST) Subject: [pypy-svn] r59005 - pypy/dist/pypy/module/marshal Message-ID: <20081011171845.595EC16A289@codespeak.net> Author: xoraxax Date: Sat Oct 11 19:18:44 2008 New Revision: 59005 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py Log: Add a timer for marshal loads. Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Sat Oct 11 19:18:44 2008 @@ -54,8 +54,11 @@ def loads(space, w_str): """Convert a string back to a value. Extra characters in the string are ignored.""" + space.timer.start("marshal loads") u = StringUnmarshaller(space, w_str) - return u.get_w_obj(False) + obj = u.get_w_obj(False) + space.timer.stop("marshal loads") + return obj class AbstractReaderWriter(object): From xoraxax at codespeak.net Sat Oct 11 19:19:29 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 11 Oct 2008 19:19:29 +0200 (CEST) Subject: [pypy-svn] r59006 - pypy/dist/pypy/module/__builtin__ Message-ID: <20081011171929.44B0C16A298@codespeak.net> Author: xoraxax Date: Sat Oct 11 19:19:28 2008 New Revision: 59006 Modified: pypy/dist/pypy/module/__builtin__/importing.py Log: Add timer in the importhook to be able to track the time needed to import a module. Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Sat Oct 11 19:19:28 2008 @@ -135,6 +135,8 @@ def importhook(space, modulename, w_globals=None, w_locals=None, w_fromlist=None): + timername = "importhook " + modulename + space.timer.start(timername) if not modulename: raise OperationError( space.w_ValueError, @@ -173,6 +175,7 @@ len(ctxt_name_prefix_parts), w_fromlist, tentative=1) if w_mod is not None: + space.timer.stop(timername) return w_mod else: rel_modulename = None @@ -180,6 +183,7 @@ w_mod = absolute_import(space, modulename, 0, w_fromlist, tentative=0) if rel_modulename is not None: space.setitem(space.sys.get('modules'), w(rel_modulename),space.w_None) + space.timer.stop(timername) return w_mod # importhook.unwrap_spec = [ObjSpace,str,W_Root,W_Root,W_Root] From cami at codespeak.net Sat Oct 11 19:52:10 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Sat, 11 Oct 2008 19:52:10 +0200 (CEST) Subject: [pypy-svn] r59007 - pypy/dist/pypy/lang/gameboy/debug Message-ID: <20081011175210.DD1A216A278@codespeak.net> Author: cami Date: Sat Oct 11 19:52:08 2008 New Revision: 59007 Modified: pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Log: smaller changes. remote debugger can now launch the python pdb Modified: pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py Sat Oct 11 19:52:08 2008 @@ -337,6 +337,8 @@ try: if int(read) > 0: self.pending_steps = int(read) + if read == "pdb": + pdb.set_trace() except Exception: if ("stop" in read) or ("exit" in read) or (read is "Q"): raise Exception("Debug mode Stopped by User") Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Sat Oct 11 19:52:08 2008 @@ -78,6 +78,6 @@ # START ======================================================================== parse_file_name() threading.Timer(1, start_java_version).start() -start_python_version() +threading.Timer(0.001, start_python_version()).start() From arigo at codespeak.net Sat Oct 11 19:56:19 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 11 Oct 2008 19:56:19 +0200 (CEST) Subject: [pypy-svn] r59008 - in pypy/trunk/pypy/module/_sre: . test Message-ID: <20081011175619.5D2A016A298@codespeak.net> Author: arigo Date: Sat Oct 11 19:56:18 2008 New Revision: 59008 Modified: pypy/trunk/pypy/module/_sre/app_sre.py pypy/trunk/pypy/module/_sre/test/test_app_sre.py Log: Test and fix for a strange type rule of CPython. Modified: pypy/trunk/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/trunk/pypy/module/_sre/app_sre.py (original) +++ pypy/trunk/pypy/module/_sre/app_sre.py Sat Oct 11 19:56:18 2008 @@ -106,6 +106,9 @@ else: state.start = state.string_position + if n == 0: # not just an optimization -- see test_sub_unicode + return string, n + if last_pos < state.end: sublist.append(string[last_pos:state.end]) if need_unicode: Modified: pypy/trunk/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/trunk/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/trunk/pypy/module/_sre/test/test_app_sre.py Sat Oct 11 19:56:18 2008 @@ -182,6 +182,11 @@ def test_sub_unicode(self): import re assert isinstance(re.sub(u"a", u"b", u""), unicode) + # the input is returned unmodified if no substitution is performed, + # which (if interpreted literally, as CPython does) gives the + # following strangeish rules: + assert isinstance(re.sub(u"a", u"b", "diwoiioamoi"), unicode) + assert isinstance(re.sub(u"a", u"b", "diwoiiobmoi"), str) def test_sub_callable(self): import re From pedronis at codespeak.net Sun Oct 12 11:13:21 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 12 Oct 2008 11:13:21 +0200 (CEST) Subject: [pypy-svn] r59012 - in pypy/build/bot2/pypybuildbot: . test Message-ID: <20081012091321.2D88116A1E8@codespeak.net> Author: pedronis Date: Sun Oct 12 11:13:20 2008 New Revision: 59012 Modified: pypy/build/bot2/pypybuildbot/summary.py pypy/build/bot2/pypybuildbot/test/test_summary.py Log: (hpk, pedronis) show the number of passed tests too Modified: pypy/build/bot2/pypybuildbot/summary.py ============================================================================== --- pypy/build/bot2/pypybuildbot/summary.py (original) +++ pypy/build/bot2/pypybuildbot/summary.py Sun Oct 12 11:13:20 2008 @@ -39,6 +39,10 @@ if longrepr: self.longreprs[namekey] = longrepr + @property + def numpassed(self): + return len(self._outcomes) - len(self.skipped) - len(self.failed) + def populate(self, log): kind = None def add_one(): @@ -133,6 +137,7 @@ self.map = map self._failed = None self._skipped = None + self._numpassed = None self.revision = map.values()[0].revision @property @@ -153,6 +158,15 @@ outcome.skipped]) return self._skipped + @property + def numpassed(self): + if self._numpassed is None: + numpassed = 0 + for prefix, outcome in self.map.items(): + numpassed += outcome.numpassed + self._numpassed = numpassed + return self._numpassed + def get_outcome(self, namekey): which = namekey[0] if which not in self.map: @@ -211,9 +225,10 @@ for cachekey, (run, url) in stdios: builder = cachekey[0] anchors.append(' ') - text = "%s [%d failed; %d skipped]" % (builder, - len(run.failed), - len(run.skipped)) + text = "%s [%d, %d F, %d s]" % (builder, + run.numpassed, + len(run.failed), + len(run.skipped)) anchors.append(html.a(text, href=url)) return anchors Modified: pypy/build/bot2/pypybuildbot/test/test_summary.py ============================================================================== --- pypy/build/bot2/pypybuildbot/test/test_summary.py (original) +++ pypy/build/bot2/pypybuildbot/test/test_summary.py Sun Oct 12 11:13:20 2008 @@ -18,6 +18,7 @@ assert rev_outcome_set.skipped == set([("a.b","test_three")]) assert rev_outcome_set.failed == set([("a.b", "test_one")]) + assert rev_outcome_set.numpassed == 1 res = rev_outcome_set.get_outcome(("a.b", "test_one")) assert res == 'F' @@ -51,6 +52,7 @@ assert len(rev_outcome_set.skipped) == 1 assert len(rev_outcome_set.failed) == 1 + assert rev_outcome_set.numpassed == 1 assert rev_outcome_set.longreprs == { ("a.b","test_three"): "some skip\n", @@ -80,6 +82,8 @@ assert rev_outcome_set.skipped == set([ ("a.c", '')]) + + assert rev_outcome_set.numpassed == 0 def test_absent_outcome(self): rev_outcome_set = summary.RevisionOutcomeSet(50000) @@ -162,6 +166,7 @@ assert goutcome.skipped == set([('foo', 'a.b', 'test_three'), ('bar', 'a.b', 'test_three'), ]) + assert goutcome.numpassed == 3 for prefix in ('foo', 'bar'): for mod, testname in (("a.b", "test_one"), ("a.b", "test_two"), @@ -182,6 +187,8 @@ assert goutcome_top.failed == set([('sub', 'foo', 'a.b', 'test_one')]) + assert goutcome_top.numpassed == 3 + res = goutcome_top.get_outcome(('sub', 'foo', 'a.b', 'test_one')) assert res == 'F' From arigo at codespeak.net Sun Oct 12 11:25:59 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 11:25:59 +0200 (CEST) Subject: [pypy-svn] r59013 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081012092559.619CA16A240@codespeak.net> Author: arigo Date: Sun Oct 12 11:25:57 2008 New Revision: 59013 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Start tests and work on exceptions. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 11:25:57 2008 @@ -1,5 +1,6 @@ from pypy.objspace.flow.model import Variable, Constant, Block, Link from pypy.objspace.flow.model import SpaceOperation, FunctionGraph, copygraph +from pypy.objspace.flow.model import c_last_exception from pypy.translator.backendopt.support import log from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import lltype @@ -458,10 +459,21 @@ block = currentframe.sourceblock self.specblock.exitswitch = self.rename_nonvirtual(block.exitswitch, 'exitswitch') + catch_exc = self.specblock.exitswitch == c_last_exception newlinks = [] for link in block.exits: - targetnodes = {} + is_exc_link = catch_exc and link.exitcase is not None + if is_exc_link: + extravars = [] + for attr in ['last_exception', 'last_exc_value']: + v = getattr(link, attr) + if isinstance(v, Variable): + rtnode = RuntimeSpecNode(v, v.concretetype) + self.setnode(v, rtnode) + self.renamings[rtnode] = v = rtnode.newvar() + extravars.append(v) + targetnodes = {} rtnodes = [] for v1, v2 in zip(link.args, link.target.inputargs): node = self.getnode(v1) @@ -494,7 +506,10 @@ linkargs = [self.renamings[rtnode] for rtnode in rtnodes] newlink = Link(linkargs, specblock) newlink.exitcase = link.exitcase - newlink.llexitcase = link.llexitcase + if hasattr(link, 'llexitcase'): + newlink.llexitcase = link.llexitcase + if is_exc_link: + newlink.extravars(*extravars) newlinks.append(newlink) self.specblock.closeblock(*newlinks) @@ -675,6 +690,10 @@ # don't include the variables produced by the current or future operations for op in block.operations[index:]: seen[op.result] = True + # don't include the extra vars produced by exception-catching links + for link in block.exits: + for v in link.getextravars(): + seen[v] = True # but include the variables consumed by the current or any future operation for op in block.operations[index:]: for v in op.args: Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 11:25:57 2008 @@ -1,4 +1,5 @@ import py +import sys from pypy.translator.backendopt.mallocv import MallocVirtualizer from pypy.translator.backendopt.inline import inline_function from pypy.translator.backendopt.all import backend_optimizations @@ -6,12 +7,20 @@ from pypy.translator import simplify from pypy.objspace.flow.model import checkgraph, flatten, Block, mkentrymap from pypy.objspace.flow.model import summary -from pypy.rpython.llinterp import LLInterpreter +from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype from pypy.rlib import objectmodel +from pypy.rlib.rarithmetic import ovfcheck from pypy.conftest import option +DONT_CHECK_RESULT = object() +class CHECK_RAISES: + def __init__(self, excname): + assert isinstance(excname, str) + self.excname = excname + + class BaseMallocRemovalTest(object): type_system = None MallocRemover = None @@ -52,10 +61,15 @@ if progress and option.view: t.view() t.checkgraphs() - if expected_result is not Ellipsis: + if expected_result is not DONT_CHECK_RESULT: interp = LLInterpreter(t.rtyper) - res = interp.eval_graph(graph, args) - assert res == expected_result + if not isinstance(expected_result, CHECK_RAISES): + res = interp.eval_graph(graph, args) + assert res == expected_result + else: + excinfo = py.test.raises(LLException, + interp.eval_graph, graph, args) + assert expected_result.excname in str(excinfo.value) if not progress: break maxiter -= 1 @@ -165,6 +179,110 @@ graph = self.check(f, [int], [19], 42, expected_calls=0) # inlined + def test_catch_simple(self): + class A: + pass + class E(Exception): + def __init__(self, n): + self.n = n + def g(n): + if n < 0: + raise E(n) + def f(n): + a = A() + a.n = 10 + try: + g(n) + except E, e: + a.n = e.n + return a.n + self.check(f, [int], [15], 10, expected_calls=1) + self.check(f, [int], [-15], -15, expected_calls=1) + + def test_raise_catch(self): + class A: + pass + class E(Exception): + def __init__(self, n): + self.n = n + def f(n): + a = A() + e1 = E(n) + try: + raise e1 + except E, e: + a.n = e.n + return a.n + self.check(f, [int], [15], 15) + + def test_raising_op(self): + class A: + pass + def f(n): + a = A() + a.n = n + try: + a.n = ovfcheck(a.n + 1) + except OverflowError: + return -42 + return a.n + self.check(f, [int], [19], 20) + self.check(f, [int], [sys.maxint], -42) + + def test_raises_through_spec_graph(self): + class A: + pass + def g(a): + if a.n < 0: + raise ValueError + def f(n): + a = A() + a.n = n + g(a) + return a.n + self.check(f, [int], [19], 19, + expected_calls=1) + self.check(f, [int], [-19], CHECK_RAISES("ValueError"), + expected_calls=1) + + def test_raises_through_inlining(self): + py.test.skip("in-progress") + class A: + pass + def g(a): + a.n -= 1 + if a.n < 0: + raise ValueError + def f(n): + a = A() + a.n = n + g(a) + return a.n + self.check(f, [int], [19], 18) + self.check(f, [int], [-19], CHECK_RAISES("ValueError")) + + def test_call_raise_catch(self): + py.test.skip("in-progress") + class A: + pass + def g(a): + a.n -= 1 + if a.n <= 0: + raise StopIteration + return a.n * 10 + def f(n): + a = A() + a.n = n + total = 0 + try: + while True: + total += g(a) + except StopIteration: + pass + return total + graph = self.check(f, [int], [11], 550, + expected_calls=0) # inlined + def test_fn2(self): class T: pass @@ -445,7 +563,7 @@ x.u1.a = 3 x.u2.b = 6 return x.u1.b * x.u2.a - self.check(fn, [], [], Ellipsis) + self.check(fn, [], [], DONT_CHECK_RESULT) def test_keep_all_keepalives(self): py.test.skip("redo me") From cfbolz at codespeak.net Sun Oct 12 11:42:49 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 12 Oct 2008 11:42:49 +0200 (CEST) Subject: [pypy-svn] r59014 - pypy/extradoc/sprintinfo/october-2008 Message-ID: <20081012094249.BA63016A233@codespeak.net> Author: cfbolz Date: Sun Oct 12 11:42:49 2008 New Revision: 59014 Modified: pypy/extradoc/sprintinfo/october-2008/planning.txt Log: (all): planning for toda Modified: pypy/extradoc/sprintinfo/october-2008/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/october-2008/planning.txt (original) +++ pypy/extradoc/sprintinfo/october-2008/planning.txt Sun Oct 12 11:42:49 2008 @@ -19,17 +19,14 @@ loops are working now - - cleanup wyvern DONE - - add a py.test -A builder - look at the TODO list of the buildbot stuff - - merge the 2.5 branch (Armin, Anto, Iko) - - fix more CPython tests IN-PROGRESS - - fix translation (Iko, Carl Friedrich) - + - merge the 2.5 branch DONE + - fix more CPython tests ALWAYS PROGRESS (Anto, Iko) + - start implementing get/set/delslice on a branch MERGED - malloc-removal-directed inlining to reduce the code size SOME PROGRESS @@ -38,19 +35,30 @@ - run memory-benchmarks nightly? - - merge gc-experiments branch DONE + - builtin-profiling branch needs to be merged DONE + + - measuring startup behaviour IN-PROGRESS: problems are marshalling, compiler + + - measuring the base interpreter size DONE + + - take a quick look at marshal + + - look at compressing unicodedata DONE, other approach needed + + - add code to print statistics to mark-and-compact DONE + + - cbuild.py refactoring IN-PROGRESS (Maciek, Samuele) + + - PEPM abstract (Carl Friedrich, Armin) - - builtin-profiling branch needs to be merged (Armin, Anto) + - fix stackless stuff (Armin, Carl Friedrich) - - setting up a scratchbox environment DONE - - measuring startup behaviour (Alexander, Holger) + - clean up the room (all) - - add code to print statistics to mark-and-compact (Alexander, Holger, Carl Friedrich) + - take over the world plan (Holger, Alexander) - - cbuild.py refactoring (Maciek, Samuele) Discussion Tasks: - - JIT roadmap - - C++ bindings? - - release plans, goals at 17.00 today + - JIT roadmap after planning session + - C++ bindings? 15.00 today DONE From iko at codespeak.net Sun Oct 12 12:46:17 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Sun, 12 Oct 2008 12:46:17 +0200 (CEST) Subject: [pypy-svn] r59015 - in pypy/dist/pypy/module/unicodedata: . test Message-ID: <20081012104617.16C8616A152@codespeak.net> Author: iko Date: Sun Oct 12 12:46:16 2008 New Revision: 59015 Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py Log: Use lists instead of dict for unicode names Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/generate_unicodedb.py (original) +++ pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Sun Oct 12 12:46:16 2008 @@ -313,20 +313,68 @@ print >> outfile, 'def combining(code): return _get_record(code)[4]' def write_character_names(outfile, table): - # Compressed Character names + def findranges(d): + ranges = [] + for i in range(max(d)+1): + if i in d: + if not ranges: + ranges.append((i,i)) + last = i + continue + if last + 1 == i: + ranges[-1] = (ranges[-1][0], i) + else: + ranges.append((i,i)) + last = i + return ranges + + def collapse_ranges(ranges): + collapsed = [ranges[0]] + for i in range(1,len(ranges)): + lows, lowe = collapsed[-1] + highs, highe = ranges[i] + if highs - lowe < max([lowe - lows, highe - highs]): + collapsed[-1] = (lows, highe) + else: + collapsed.append(ranges[i]) + + return collapsed + names = [table[code].name for code in range(len(table)) if table[code].name] codelist = compression.build_compression_table(names) - print >> outfile, '_charnames = {' - for code in range(len(table)): - name = table[code].name - if name: - print >> outfile, '%r: %r,' % ( - code, compression.compress(codelist, name)) - print >> outfile, "}\n" print >> outfile, "_codelist =", pprint.pprint(codelist, outfile) + codes = set(code for code in range(len(table)) if table[code].name) + ranges = collapse_ranges(findranges(codes)) + f_reverse_dict = ["def _gen_reverse_dict():", + " res = {}"] + function = ["def lookup_charcode(code):", + " from pypy.module.unicodedata import compression", + " res = None"] + for low, high in ranges: + function.append( + " if %d <= code <= %d: res = _charnames_%d[code-%d]" % ( + low, high, low, low)) + f_reverse_dict.append( + " for i in range(%d, %d): res[_charnames_%d[i-%d]] = i" % ( + low, high+1, low, low)) + print >> outfile, "_charnames_%d = [" % (low,) + for code in range(low, high + 1): + name = table[code].name + if name: + print >> outfile, '%r,' % ( + compression.compress(codelist, name)) + else: + print >> outfile, 'None,' + print >> outfile, "]\n" + function.extend([" if res is None: raise KeyError, code", + " return compression.uncompress(_codelist, res)\n"]) + print >> outfile, '\n'.join(function) + f_reverse_dict.append(" return res\n") + print >> outfile, '\n'.join(f_reverse_dict) + def writeUnicodedata(version, table, outfile): # Version print >> outfile, 'version = %r' % version @@ -339,7 +387,7 @@ write_character_names(outfile, table) print >> outfile, ''' -_code_by_name = dict(map(lambda x:(x[1],x[0]), _charnames.iteritems())) +_code_by_name = _gen_reverse_dict() _cjk_prefix = "CJK UNIFIED IDEOGRAPH-" _hangul_prefix = 'HANGUL SYLLABLE ' @@ -407,7 +455,6 @@ return _code_by_name[compression.compress(_codelist, name)] def name(code): - from pypy.module.unicodedata import compression if (0x3400 <= code <= 0x4DB5 or 0x4E00 <= code <= 0x%X or 0x20000 <= code <= 0x2A6D6): @@ -422,7 +469,7 @@ return ("HANGUL SYLLABLE " + _hangul_L[l_code] + _hangul_V[v_code] + _hangul_T[t_code]) - return compression.uncompress(_codelist, _charnames[code]) + return lookup_charcode(code) ''' % (cjk_end, cjk_end) # Categories Modified: pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py (original) +++ pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py Sun Oct 12 12:46:16 2008 @@ -10,7 +10,8 @@ space = gettestobjspace(usemodules=('unicodedata',)) cls.space = space charlist_w = [] - for i in range(2000): + nocharlist_w = [] + while len(charlist_w) < 1000 or len(nocharlist_w) < 1000: chr = unichr(random.randrange(65536)) try: w_tup = space.newtuple([ @@ -19,8 +20,9 @@ ]) charlist_w.append(w_tup) except ValueError: - pass + nocharlist_w.append(space.wrap(chr)) cls.w_charlist = space.newlist(charlist_w) + cls.w_nocharlist = space.newlist(nocharlist_w) def test_hangul_syllables(self): import unicodedata @@ -93,3 +95,7 @@ assert unicodedata.name(chr) == name assert unicodedata.lookup(name) == chr + def test_random_missing_chars(self): + import unicodedata + for chr in self.nocharlist: + raises(ValueError, unicodedata.name, chr) From iko at codespeak.net Sun Oct 12 13:35:05 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Sun, 12 Oct 2008 13:35:05 +0200 (CEST) Subject: [pypy-svn] r59016 - pypy/dist/pypy/module/unicodedata Message-ID: <20081012113505.52B1516A1FC@codespeak.net> Author: iko Date: Sun Oct 12 13:35:03 2008 New Revision: 59016 Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Log: Make sure code points exists before adding them to reverse dict Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/generate_unicodedb.py (original) +++ pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Sun Oct 12 13:35:03 2008 @@ -357,9 +357,12 @@ function.append( " if %d <= code <= %d: res = _charnames_%d[code-%d]" % ( low, high, low, low)) - f_reverse_dict.append( - " for i in range(%d, %d): res[_charnames_%d[i-%d]] = i" % ( - low, high+1, low, low)) + f_reverse_dict.extend([ + " for i in range(%d, %d):" % (low, high+1), + " name = _charnames_%d[i-%d]" % (low, low), + " if name is not None:", + " res[name] = i", + ]) print >> outfile, "_charnames_%d = [" % (low,) for code in range(low, high + 1): name = table[code].name From antocuni at codespeak.net Sun Oct 12 13:58:18 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 12 Oct 2008 13:58:18 +0200 (CEST) Subject: [pypy-svn] r59017 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081012115818.2314416A2CF@codespeak.net> Author: antocuni Date: Sun Oct 12 13:58:17 2008 New Revision: 59017 Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py pypy/trunk/pypy/objspace/std/unicodeobject.py Log: (antocuni, iko) raise OverflowError if the unicode string you are building seems to be too big Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Sun Oct 12 13:58:17 2008 @@ -247,6 +247,13 @@ assert u'123123'.replace('123', u'') == u'' assert u'123x123'.replace(u'123', u'') == u'x' + def test_replace_overflow(self): + import sys + if sys.maxint > 2**31-1: + skip("Wrong platform") + s = u"a" * (2**16) + raises(OverflowError, s.replace, u"", s) + def test_strip(self): s = u" a b " assert s.strip() == u"a b" Modified: pypy/trunk/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/unicodeobject.py Sun Oct 12 13:58:17 2008 @@ -799,6 +799,14 @@ self = w_self._value maxsplit = space.int_w(w_maxsplit) parts = _split_into_chars(self, maxsplit) + + try: + ovfcheck(len(parts) * len(w_new._value) + len(w_self._value)) + except OverflowError: + raise OperationError( + space.w_OverflowError, + space.wrap("replace string is too long")) + return W_UnicodeObject(w_new._value.join(parts)) From arigo at codespeak.net Sun Oct 12 14:13:40 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 14:13:40 +0200 (CEST) Subject: [pypy-svn] r59018 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081012121340.D33EA16A153@codespeak.net> Author: arigo Date: Sun Oct 12 14:13:38 2008 New Revision: 59018 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Refactorings. No more tests pass. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 14:13:38 2008 @@ -105,9 +105,11 @@ class VirtualFrame(object): - def __init__(self, sourceblock, nextopindex, allnodes, callerframe=None): + def __init__(self, sourcegraph, sourceblock, nextopindex, + allnodes, callerframe=None): self.varlist = vars_alive_through_op(sourceblock, nextopindex) self.nodelist = [allnodes[v] for v in self.varlist] + self.sourcegraph = sourcegraph self.sourceblock = sourceblock self.nextopindex = nextopindex self.callerframe = callerframe @@ -120,6 +122,7 @@ newframe.varlist = self.varlist newframe.nodelist = [node.copy(memo, flagreadonly) for node in self.nodelist] + newframe.sourcegraph = self.sourcegraph newframe.sourceblock = self.sourceblock newframe.nextopindex = self.nextopindex if self.callerframe is None: @@ -160,15 +163,24 @@ rtnodes, vtnodes = self.find_all_nodes() return vtnodes - def return_to_caller(self, returnblock, targetnodes): - [v_ret] = returnblock.inputargs - retnode = targetnodes[v_ret] + def return_to_caller(self, retnode): callerframe = self.callerframe + if callerframe is None: + raise ForcedInline("return block") for i in range(len(callerframe.nodelist)): if isinstance(callerframe.nodelist[i], FutureReturnValue): callerframe.nodelist[i] = retnode return callerframe + def handle_raise(self, linkargsnodes): + if not is_trivial_nodelist(linkargsnodes): + raise ForcedInline("except block") + # XXX this assumes no exception handler in the callerframes + topframe = self + while topframe.callerframe is not None: + topframe = topframe.callerframe + return topframe, topframe.sourcegraph.exceptblock + def copynodes(nodelist, flagreadonly={}): memo = {} @@ -264,10 +276,10 @@ def try_remove_malloc(self, graph, block, op): if (graph, op) in self.inline_and_remove_seen: return False # no point in trying again - graphbuilder = GraphBuilder(self) + graphbuilder = GraphBuilder(self, graph) if graph in self.graphbuilders: graphbuilder.initialize_from_old_builder(self.graphbuilders[graph]) - graphbuilder.start_from_a_malloc(block, op.result) + graphbuilder.start_from_a_malloc(graph, block, op.result) try: graphbuilder.propagate_specializations() except CannotVirtualize, e: @@ -305,7 +317,7 @@ if is_trivial_nodelist(nodelist): return 'trivial', graph nodes = dict(zip(graph.getargs(), nodelist)) - virtualframe = VirtualFrame(graph.startblock, 0, nodes) + virtualframe = VirtualFrame(graph, graph.startblock, 0, nodes) key = virtualframe.getfrozenkey() try: return self.specialized_graphs[key] @@ -316,8 +328,8 @@ def build_specialized_graph(self, graph, key, nodelist): graph2 = copygraph(graph) nodes = dict(zip(graph2.getargs(), nodelist)) - virtualframe = VirtualFrame(graph2.startblock, 0, nodes) - graphbuilder = GraphBuilder(self) + virtualframe = VirtualFrame(graph2, graph2.startblock, 0, nodes) + graphbuilder = GraphBuilder(self, graph2) specblock = graphbuilder.start_from_virtualframe(virtualframe) specblock.isstartblock = True specgraph = graph2 @@ -341,8 +353,9 @@ class GraphBuilder(object): - def __init__(self, mallocv): + def __init__(self, mallocv, graph): self.mallocv = mallocv + self.graph = graph self.specialized_blocks = {} self.pending_specializations = [] @@ -355,12 +368,12 @@ self.pending_specializations.append(spec) return spec.specblock - def start_from_a_malloc(self, block, v_result): + def start_from_a_malloc(self, graph, block, v_result): assert v_result in [op.result for op in block.operations] nodes = {} for v in block.inputargs: nodes[v] = RuntimeSpecNode(v, v.concretetype) - trivialframe = VirtualFrame(block, 0, nodes) + trivialframe = VirtualFrame(graph, block, 0, nodes) spec = BlockSpecializer(self, v_result) spec.initialize_renamings(trivialframe) self.pending_specializations.append(spec) @@ -455,8 +468,7 @@ self.specblock.operations = newoperations def follow_exits(self): - currentframe = self.virtualframe - block = currentframe.sourceblock + block = self.virtualframe.sourceblock self.specblock.exitswitch = self.rename_nonvirtual(block.exitswitch, 'exitswitch') catch_exc = self.specblock.exitswitch == c_last_exception @@ -473,30 +485,30 @@ self.renamings[rtnode] = v = rtnode.newvar() extravars.append(v) - targetnodes = {} - rtnodes = [] - for v1, v2 in zip(link.args, link.target.inputargs): - node = self.getnode(v1) - if isinstance(node, RuntimeSpecNode): - rtnodes.append(node) - targetnodes[v2] = node + currentframe = self.virtualframe + linkargsnodes = [self.getnode(v1) for v1 in link.args] + targetblock = link.target + + if is_except(targetblock): + currentframe, targetblock = currentframe.handle_raise( + linkargsnodes) + + assert len(targetblock.inputargs) == len(linkargsnodes) + targetnodes = dict(zip(targetblock.inputargs, linkargsnodes)) - if (len(rtnodes) == len(link.args) and - currentframe.callerframe is None): + if (currentframe.callerframe is None and + is_trivial_nodelist(linkargsnodes)): # there is no more VirtualSpecNodes being passed around, - # so we can stop specializing. - specblock = link.target + # so we can stop specializing + rtnodes = linkargsnodes + specblock = targetblock else: - if len(link.target.exits) == 0: # return or except block - if len(link.target.inputargs) != 1: - raise CannotVirtualize("except block") - if currentframe.callerframe is None: - raise ForcedInline("return block") - newframe = currentframe.return_to_caller(link.target, - targetnodes) + if is_return(targetblock): + newframe = currentframe.return_to_caller(linkargsnodes[0]) v_expand_malloc = None else: - newframe = VirtualFrame(link.target, 0, targetnodes, + newframe = VirtualFrame(currentframe.sourcegraph, + targetblock, 0, targetnodes, callerframe=currentframe.callerframe) v_expand_malloc = self.v_expand_malloc rtnodes = newframe.find_rt_nodes() @@ -636,10 +648,11 @@ raise ValueError(kind) def get_updated_frame(self, op): + sourcegraph = self.virtualframe.sourcegraph sourceblock = self.virtualframe.sourceblock nextopindex = self.virtualframe.nextopindex self.nodes[op.result] = FutureReturnValue(op) - myframe = VirtualFrame(sourceblock, nextopindex, + myframe = VirtualFrame(sourcegraph, sourceblock, nextopindex, self.nodes, self.virtualframe.callerframe) del self.nodes[op.result] @@ -657,7 +670,7 @@ def handle_inlined_call(self, myframe, graph, newnodes): assert len(graph.getargs()) == len(newnodes) targetnodes = dict(zip(graph.getargs(), newnodes)) - calleeframe = VirtualFrame(graph.startblock, 0, + calleeframe = VirtualFrame(graph, graph.startblock, 0, targetnodes, myframe) self.virtualframe = calleeframe self.nodes = calleeframe.get_nodes_in_use() @@ -703,3 +716,9 @@ for v in link.args: see(v) return result + +def is_return(block): + return len(block.exits) == 0 and len(block.inputargs) == 1 + +def is_except(block): + return len(block.exits) == 0 and len(block.inputargs) == 2 Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 14:13:38 2008 @@ -179,6 +179,18 @@ graph = self.check(f, [int], [19], 42, expected_calls=0) # inlined + def test_raises_simple(self): + class MyExc(Exception): + pass + def f(n): + if n < 3: + e = MyExc() + e.n = n + raise e + return n + self.check(f, [int], [5], 5, expected_mallocs=1) + self.check(f, [int], [-5], CHECK_RAISES("MyExc"), expected_mallocs=1) + def test_catch_simple(self): class A: pass @@ -192,7 +204,7 @@ a = A() a.n = 10 try: - g(n) + g(n) # this call should not be inlined except E, e: a.n = e.n return a.n From arigo at codespeak.net Sun Oct 12 14:17:09 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 14:17:09 +0200 (CEST) Subject: [pypy-svn] r59019 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081012121709.11E8116A1A4@codespeak.net> Author: arigo Date: Sun Oct 12 14:17:09 2008 New Revision: 59019 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: This test passes now. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 14:17:09 2008 @@ -179,7 +179,16 @@ topframe = self while topframe.callerframe is not None: topframe = topframe.callerframe - return topframe, topframe.sourcegraph.exceptblock + targetblock = topframe.sourcegraph.exceptblock + self.fixup_except_block(targetblock) + return topframe, targetblock + + def fixup_except_block(self, block): + # hack: this block's inputargs may be missing concretetypes... + e1, v1 = block.inputargs + e2, v2 = self.sourcegraph.exceptblock.inputargs + e1.concretetype = e2.concretetype + v1.concretetype = v2.concretetype def copynodes(nodelist, flagreadonly={}): Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 14:17:09 2008 @@ -258,7 +258,6 @@ expected_calls=1) def test_raises_through_inlining(self): - py.test.skip("in-progress") class A: pass def g(a): From arigo at codespeak.net Sun Oct 12 14:20:33 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 14:20:33 +0200 (CEST) Subject: [pypy-svn] r59020 - pypy/dist/pypy/translator/backendopt Message-ID: <20081012122033.E5C1E16A271@codespeak.net> Author: arigo Date: Sun Oct 12 14:20:33 2008 New Revision: 59020 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py Log: For now, let's not try to inline functions that raise freshly-malloced exceptions. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 14:20:33 2008 @@ -174,7 +174,11 @@ def handle_raise(self, linkargsnodes): if not is_trivial_nodelist(linkargsnodes): - raise ForcedInline("except block") + raise CannotVirtualize("except block") + # ^^^ this could also be a ForcedInline, to try to match the + # exception raising and catching globally. But it looks + # overkill for now. + # XXX this assumes no exception handler in the callerframes topframe = self while topframe.callerframe is not None: From pedronis at codespeak.net Sun Oct 12 14:20:52 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 12 Oct 2008 14:20:52 +0200 (CEST) Subject: [pypy-svn] r59021 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081012122052.77FDE16A25B@codespeak.net> Author: pedronis Date: Sun Oct 12 14:20:52 2008 New Revision: 59021 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Log: attach more information to the makefile object Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sun Oct 12 14:20:52 2008 @@ -68,9 +68,18 @@ f.write('# %s\n' % (self.body,)) class GnuMakefile(object): - def __init__(self): + def __init__(self, path=None): self.defs = {} self.lines = [] + self._path = py.path.local(path) + + def pathrel(self, fpath): + if fpath.dirpath() == self._path: + return fpath.basename + elif fpath.dirpath().dirpath() == self._path.dirpath(): + return '../' + fpath.relto(self._path.dirpath()) + else: + return str(fpath) def definition(self, name, value): defs = self.defs @@ -180,21 +189,15 @@ if path is None: path = cfiles[0].dirpath() - else: - path = py.path.local(path) pypypath = py.path.local(autopath.pypydir) if exe_name is None: exe_name = cfiles[0].new(ext='') - def pathrel(fpath): - if fpath.dirpath() == path: - return fpath.basename - elif fpath.dirpath().dirpath() == path.dirpath(): - return '../' + fpath.relto(path.dirpath()) - else: - return str(fpath) + m = GnuMakefile(path) + m.exe_name = exe_name + m.eci = eci def pypyrel(fpath): rel = py.path.local(fpath).relto(pypypath) @@ -203,12 +206,11 @@ else: return fpath - rel_cfiles = [pathrel(cfile) for cfile in cfiles] + rel_cfiles = [m.pathrel(cfile) for cfile in cfiles] rel_ofiles = [rel_cfile[:-2]+'.o' for rel_cfile in rel_cfiles] rel_includedirs = [pypyrel(incldir) for incldir in eci.include_dirs] - m = GnuMakefile() m.comment('automatically generated makefile') definitions = [ ('PYPYDIR', autopath.pypydir), From pedronis at codespeak.net Sun Oct 12 14:25:14 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 12 Oct 2008 14:25:14 +0200 (CEST) Subject: [pypy-svn] r59023 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test Message-ID: <20081012122514.993F616A0BC@codespeak.net> Author: pedronis Date: Sun Oct 12 14:25:11 2008 New Revision: 59023 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Log: by default write Makefile to own path Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sun Oct 12 14:25:11 2008 @@ -96,10 +96,16 @@ def comment(self, body): self.lines.append(Comment(body)) - def write(self, f): + def write(self, out=None): + if out is None: + f = self._path.join('Makefile').open('w') + else: + f = out for line in self.lines: line.write(f) f.flush() + if out is None: + f.close() class Linux(Platform): link_flags = ['-pthread'] Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Sun Oct 12 14:25:11 2008 @@ -23,9 +23,7 @@ ''') mk = host.gen_makefile([cfile], ExternalCompilationInfo(), path=tmpdir) - f = tmpdir.join('Makefile').open('w') - mk.write(f) - f.close() + mk.write() host.execute_makefile(tmpdir) res = host.execute(tmpdir.join('test_simple_enough')) assert res.out == '42\n' From antocuni at codespeak.net Sun Oct 12 14:28:17 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 12 Oct 2008 14:28:17 +0200 (CEST) Subject: [pypy-svn] r59024 - in pypy/trunk/pypy: module/_codecs objspace/std/test Message-ID: <20081012122817.3B03C16A252@codespeak.net> Author: antocuni Date: Sun Oct 12 14:28:16 2008 New Revision: 59024 Modified: pypy/trunk/pypy/module/_codecs/app_codecs.py pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Log: (antocuni, iko) fix a bug introduced when converting PyUnicode_DecodeRawUnicodeEscape from C to Python Modified: pypy/trunk/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/trunk/pypy/module/_codecs/app_codecs.py (original) +++ pypy/trunk/pypy/module/_codecs/app_codecs.py Sun Oct 12 14:28:16 2008 @@ -892,6 +892,10 @@ break p += unichr(ord(s[pos])) pos += 1 + + # we have a backlash at the end of the string, stop here + if pos >= size: + break if (((pos - bs) & 1) == 0 or pos >= size or Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Sun Oct 12 14:28:16 2008 @@ -659,3 +659,7 @@ def test_no_len_on_str_iter(self): iterable = u"hello" raises(TypeError, len, iter(iterable)) + + def test_encode_raw_unicode_escape(self): + u = unicode('\\', 'raw_unicode_escape') + assert u == u'\\' From pedronis at codespeak.net Sun Oct 12 14:34:30 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 12 Oct 2008 14:34:30 +0200 (CEST) Subject: [pypy-svn] r59025 - in pypy/branch/cbuild-refactor/pypy/translator: c/test platform platform/test Message-ID: <20081012123430.657CF16A2C6@codespeak.net> Author: pedronis Date: Sun Oct 12 14:34:29 2008 New Revision: 59025 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Log: let's execute makefile objects directly Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Sun Oct 12 14:34:29 2008 @@ -189,7 +189,6 @@ assert data.strip() == "OK" def test_separate_files(): - py.test.skip("Skip for now") # One file in translator/c/src fname = py.path.local(pypydir).join( 'translator', 'c', 'src', 'll_strtod.h') Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sun Oct 12 14:34:29 2008 @@ -71,13 +71,13 @@ def __init__(self, path=None): self.defs = {} self.lines = [] - self._path = py.path.local(path) + self.makefile_dir = py.path.local(path) def pathrel(self, fpath): - if fpath.dirpath() == self._path: + if fpath.dirpath() == self.makefile_dir: return fpath.basename - elif fpath.dirpath().dirpath() == self._path.dirpath(): - return '../' + fpath.relto(self._path.dirpath()) + elif fpath.dirpath().dirpath() == self.makefile_dir.dirpath(): + return '../' + fpath.relto(self.makefile_dir.dirpath()) else: return str(fpath) @@ -98,7 +98,7 @@ def write(self, out=None): if out is None: - f = self._path.join('Makefile').open('w') + f = self.makefile_dir.join('Makefile').open('w') else: f = out for line in self.lines: @@ -245,7 +245,11 @@ return m - def execute_makefile(self, path): + def execute_makefile(self, path_to_makefile): + if isinstance(path_to_makefile, GnuMakefile): + path = path_to_makefile.makefile_dir + else: + path = path_to_makefile log.execute('make in %s' % (path,)) returncode, stdout, stderr = _run_subprocess('make', ['-C', str(path)]) if returncode != 0: Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Sun Oct 12 14:34:29 2008 @@ -24,7 +24,7 @@ mk = host.gen_makefile([cfile], ExternalCompilationInfo(), path=tmpdir) mk.write() - host.execute_makefile(tmpdir) + host.execute_makefile(mk) res = host.execute(tmpdir.join('test_simple_enough')) assert res.out == '42\n' assert res.err == '' From xoraxax at codespeak.net Sun Oct 12 14:36:32 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 12 Oct 2008 14:36:32 +0200 (CEST) Subject: [pypy-svn] r59026 - pypy/build/doc Message-ID: <20081012123632.0284516A2D6@codespeak.net> Author: xoraxax Date: Sun Oct 12 14:36:32 2008 New Revision: 59026 Modified: pypy/build/doc/benchmark_memory.txt Log: Add gcbench as an allocation pattern goal, mention sampling. Modified: pypy/build/doc/benchmark_memory.txt ============================================================================== --- pypy/build/doc/benchmark_memory.txt (original) +++ pypy/build/doc/benchmark_memory.txt Sun Oct 12 14:36:32 2008 @@ -41,7 +41,7 @@ and little scenarios like reading lines from a large file. also consider reuse some of the speed benchmarks. -* allocation patterns: +* allocation patterns, measure memory usage using sampling: 1. allocate objects all the time, total number of objects stays constant; 2. allocate many objects in a burst, then throw them away, @@ -49,6 +49,7 @@ 3. combined: do 1 for most of the time with a small number of live objects, but occasionally get a large bunch of objects and immediately free them. + 4. Look at gcbench Use several sets of "small" and "large". * Aim for reproducible results, e.g. by combining some of From antocuni at codespeak.net Sun Oct 12 14:40:53 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 12 Oct 2008 14:40:53 +0200 (CEST) Subject: [pypy-svn] r59027 - in pypy/trunk/pypy: module/_codecs objspace/std/test Message-ID: <20081012124053.58B10168525@codespeak.net> Author: antocuni Date: Sun Oct 12 14:40:52 2008 New Revision: 59027 Modified: pypy/trunk/pypy/module/_codecs/interp_codecs.py pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Log: (antocuni, arigo, iko) make unicode decoders accept also buffers as an argument Modified: pypy/trunk/pypy/module/_codecs/interp_codecs.py ============================================================================== --- pypy/trunk/pypy/module/_codecs/interp_codecs.py (original) +++ pypy/trunk/pypy/module/_codecs/interp_codecs.py Sun Oct 12 14:40:52 2008 @@ -222,7 +222,7 @@ result, consumed = func(string, len(string), errors, final, state.decode_error_handler) return space.newtuple([space.wrap(result), space.wrap(consumed)]) - wrap_decoder.unwrap_spec = [ObjSpace, str, str, W_Root] + wrap_decoder.unwrap_spec = [ObjSpace, 'bufferstr', str, W_Root] globals()[name] = wrap_decoder for encoders in [ Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Sun Oct 12 14:40:52 2008 @@ -663,3 +663,8 @@ def test_encode_raw_unicode_escape(self): u = unicode('\\', 'raw_unicode_escape') assert u == u'\\' + + def test_decode_from_buffer(self): + buf = buffer('character buffers are decoded to unicode') + u = unicode(buf, 'utf-8', 'strict') + assert u == u'character buffers are decoded to unicode' From iko at codespeak.net Sun Oct 12 15:00:41 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Sun, 12 Oct 2008 15:00:41 +0200 (CEST) Subject: [pypy-svn] r59029 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081012130041.31E3516A1EF@codespeak.net> Author: iko Date: Sun Oct 12 15:00:40 2008 New Revision: 59029 Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py pypy/trunk/pypy/objspace/std/unicodeobject.py Log: (iko, antocuni) Make unicode expandtabs raise OverflowError if the string would become too large Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Sun Oct 12 15:00:40 2008 @@ -399,6 +399,12 @@ assert u'xy'.expandtabs() =='xy' assert u''.expandtabs() =='' + def test_expandtabs_overflows_gracefully(self): + import sys + if sys.maxint > (1 << 32): + skip("Wrong platform") + raises(OverflowError, u't\tt\t'.expandtabs, sys.maxint) + def test_translate(self): assert u'bbbc' == u'abababc'.translate({ord('a'):None}) assert u'iiic' == u'abababc'.translate({ord('a'):None, ord('b'):ord('i')}) Modified: pypy/trunk/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/unicodeobject.py Sun Oct 12 15:00:40 2008 @@ -857,14 +857,20 @@ parts = _split_with(self, u'\t') result = [parts[0]] prevsize = 0 + totalsize = 0 for ch in parts[0]: prevsize += 1 if ch == u"\n" or ch == u"\r": prevsize = 0 + for i in range(1, len(parts)): pad = tabsize - prevsize % tabsize - result.append(u' ' * pad) nextpart = parts[i] + try: + totalsize = ovfcheck(totalsize + pad + len(nextpart)) + result.append(u' ' * pad) + except (OverflowError, MemoryError): + raise OperationError(space.w_OverflowError, space.wrap('new string is too long')) result.append(nextpart) prevsize = 0 for ch in nextpart: From fijal at codespeak.net Sun Oct 12 15:08:55 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 12 Oct 2008 15:08:55 +0200 (CEST) Subject: [pypy-svn] r59030 - in pypy/branch/cbuild-refactor/pypy/translator: c tool Message-ID: <20081012130855.CDE6616A23C@codespeak.net> Author: fijal Date: Sun Oct 12 15:08:55 2008 New Revision: 59030 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Log: (fijal, pedronis) Make test_standalone pass Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Sun Oct 12 15:08:55 2008 @@ -202,24 +202,36 @@ CBuilder.have___thread = self.translator.platform.check___thread() if not self.standalone: assert not self.config.translation.instrument - cfile, extra = gen_source(db, modulename, targetdir, self.eci, - defines = defines) + self.eci, cfile, extra = gen_source(db, modulename, targetdir, + self.eci, + defines = defines) else: if self.config.translation.instrument: defines['INSTRUMENT'] = 1 if CBuilder.have___thread: if not self.config.translation.no__thread: defines['USE___THREAD'] = 1 - cfile, extra = gen_source_standalone(db, modulename, targetdir, + self.eci, cfile, extra = gen_source_standalone(db, modulename, + targetdir, self.eci, entrypointname = pfname, defines = defines) self.c_source_filename = py.path.local(cfile) - self.extrafiles = extra - if self.standalone: - self.gen_makefile(targetdir) + self.extrafiles = self.eventually_copy(extra) + self.gen_makefile(targetdir) return cfile + def eventually_copy(self, cfiles): + extrafiles = [] + for fn in cfiles: + fn = py.path.local(fn) + if not fn.relto(udir): + newname = self.targetdir.join(fn.basename) + fn.copy(newname) + fn = newname + extrafiles.append(fn) + return extrafiles + class ModuleWithCleanup(object): def __init__(self, mod): self.__dict__['mod'] = mod @@ -336,6 +348,9 @@ if isinstance(self._module, isolate.Isolate): isolate.close_isolate(self._module) + def gen_makefile(self, targetdir): + pass + class CStandaloneBuilder(CBuilder): standalone = True executable_name = None @@ -364,22 +379,6 @@ bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) - def getccompiler(self): - cc = self.config.translation.cc - # Copy extrafiles to target directory, if needed - extrafiles = [] - for fn in self.extrafiles: - fn = py.path.local(fn) - if not fn.relto(udir): - newname = self.targetdir.join(fn.basename) - fn.copy(newname) - fn = newname - extrafiles.append(fn) - - return CCompiler( - [self.c_source_filename] + extrafiles, - self.eci, compiler_exe = cc, profbased = self.getprofbased()) - def compile(self): assert self.c_source_filename assert not self._compiled @@ -415,15 +414,14 @@ compiler.link_extra.append(self.config.translation.linkerflags) def gen_makefile(self, targetdir): + cfiles = [self.c_source_filename] + self.extrafiles + mk = self.translator.platform.gen_makefile(cfiles, self.eci, + path=targetdir) + mk.write() + #self.translator.platform, + # , + # self.eci, profbased=self.getprofbased() return - def write_list(lst, prefix): - for i, fn in enumerate(lst): - print >> f, prefix, fn, - if i < len(lst)-1: - print >> f, '\\' - else: - print >> f - prefix = ' ' * len(prefix) self.eci = self.eci.merge(ExternalCompilationInfo( includes=['.', str(self.targetdir)])) @@ -842,8 +840,8 @@ fi.close() eci = eci.convert_sources_to_files(being_main=True) - return filename, sg.getextrafiles() + list(eci.separate_module_files) - + files, eci = eci.get_module_files() + return eci, filename, sg.getextrafiles() + list(files) def gen_source(database, modulename, targetdir, eci, defines={}): assert not database.standalone @@ -902,9 +900,8 @@ f.write(SETUP_PY % locals()) f.close() eci = eci.convert_sources_to_files(being_main=True) - - return filename, sg.getextrafiles() + list(eci.separate_module_files) - + files, eci = eci.get_module_files() + return eci, filename, sg.getextrafiles() + list(files) SETUP_PY = ''' from distutils.core import setup Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Sun Oct 12 15:08:55 2008 @@ -255,6 +255,12 @@ d['separate_module_files'] += tuple(files) return ExternalCompilationInfo(**d) + def get_module_files(self): + d = self._copy_attributes() + files = d['separate_module_files'] + d['separate_module_files'] = () + return files, ExternalCompilationInfo(**d) + def compile_shared_lib(self): self = self.convert_sources_to_files() if not self.separate_module_files: From cfbolz at codespeak.net Sun Oct 12 15:11:54 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 12 Oct 2008 15:11:54 +0200 (CEST) Subject: [pypy-svn] r59031 - pypy/trunk/pypy/interpreter Message-ID: <20081012131154.1344B16A279@codespeak.net> Author: cfbolz Date: Sun Oct 12 15:11:52 2008 New Revision: 59031 Modified: pypy/trunk/pypy/interpreter/executioncontext.py Log: (cfbolz, arigo around): fix stackless failures Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Sun Oct 12 15:11:52 2008 @@ -71,7 +71,8 @@ def leave(self, ec): self.framestack = ec.framestack self.w_tracefunc = ec.w_tracefunc - self.setllprofile(ec.profilefunc, ec.w_profilefuncarg) + self.profilefunc = ec.profilefunc + self.w_profilefuncarg = ec.w_profilefuncarg self.is_tracing = ec.is_tracing # the following interface is for pickling and unpickling From fijal at codespeak.net Sun Oct 12 15:51:41 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 12 Oct 2008 15:51:41 +0200 (CEST) Subject: [pypy-svn] r59032 - in pypy/branch/cbuild-refactor/pypy/translator: c platform Message-ID: <20081012135141.E684016A1F3@codespeak.net> Author: fijal Date: Sun Oct 12 15:51:39 2008 New Revision: 59032 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Log: (fijal, pedronis) make asmgcc run again Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Sun Oct 12 15:51:39 2008 @@ -382,141 +382,62 @@ def compile(self): assert self.c_source_filename assert not self._compiled - compiler = CCompilerDriver(self.translator.platform, - [self.c_source_filename] + self.extrafiles, - self.eci, profbased=self.getprofbased()) if self.config.translation.gcrootfinder == "asmgcc": - xxx - # as we are gcc-only anyway, let's just use the Makefile. - cmdline = "make -C '%s'" % (self.targetdir,) - err = os.system(cmdline) - if err != 0: - raise OSError("failed (see output): " + cmdline) + self.translator.platform.execute_makefile(self.targetdir) else: - #self.adaptflags(compiler) + compiler = CCompilerDriver(self.translator.platform, + [self.c_source_filename] + self.extrafiles, + self.eci, profbased=self.getprofbased()) self.executable_name = compiler.build() assert self.executable_name self._compiled = True return self.executable_name - def cmdexec(self, args=''): - assert self._compiled - return py.process.cmdexec('"%s" %s' % (self.executable_name, args)) - - def adaptflags(self, compiler): - if sys.platform == 'darwin': - compiler.compile_extra.append('-mdynamic-no-pic') - if sys.platform == 'sunos5': - compiler.link_extra.append("-lrt") - if self.config.translation.compilerflags: - compiler.compile_extra.append(self.config.translation.compilerflags) - if self.config.translation.linkerflags: - compiler.link_extra.append(self.config.translation.linkerflags) - def gen_makefile(self, targetdir): cfiles = [self.c_source_filename] + self.extrafiles mk = self.translator.platform.gen_makefile(cfiles, self.eci, path=targetdir) - mk.write() - #self.translator.platform, - # , - # self.eci, profbased=self.getprofbased() - return - - self.eci = self.eci.merge(ExternalCompilationInfo( - includes=['.', str(self.targetdir)])) - compiler = self.getccompiler() - - self.adaptflags(compiler) - assert self.config.translation.gcrootfinder != "llvmgc" - cfiles = [] - ofiles = [] - gcmapfiles = [] - for fn in compiler.cfilenames: - fn = py.path.local(fn) - if fn.dirpath() == targetdir: - name = fn.basename - else: - assert fn.dirpath().dirpath() == udir - name = '../' + fn.relto(udir) - - name = name.replace("\\", "/") - cfiles.append(name) - if self.config.translation.gcrootfinder == "asmgcc": - ofiles.append(name[:-2] + '.s') - gcmapfiles.append(name[:-2] + '.gcmap') - else: - ofiles.append(name[:-2] + '.o') - - if self.config.translation.cc: - cc = self.config.translation.cc - else: - cc = self.eci.platform.get_compiler() - if cc is None: - cc = 'gcc' - make_no_prof = '' + mk.definition('ABS_TARGET', '$(shell python -c "import sys,os; print os.path.abspath(sys.argv[1])" $(TARGET))') if self.has_profopt(): profopt = self.config.translation.profopt - default_target = 'profopt' - # XXX horrible workaround for a bug of profiling in gcc on - # OS X with functions containing a direct call to fork() - non_profilable = [] - assert len(compiler.cfilenames) == len(ofiles) - for fn, oname in zip(compiler.cfilenames, ofiles): - fn = py.path.local(fn) - if '/*--no-profiling-for-this-file!--*/' in fn.read(): - non_profilable.append(oname) - if non_profilable: - make_no_prof = '$(MAKE) %s' % (' '.join(non_profilable),) - else: - profopt = '' - default_target = '$(TARGET)' + mk.definition('DEFAULT_TARGET', 'profopt') + mk.definition('PROFOPT', profopt) - f = targetdir.join('Makefile').open('w') - print >> f, '# automatically generated Makefile' - print >> f - print >> f, 'PYPYDIR =', autopath.pypydir - print >> f - print >> f, 'TARGET =', py.path.local(compiler.outputfilename).basename - print >> f - print >> f, 'DEFAULT_TARGET =', default_target - print >> f - write_list(cfiles, 'SOURCES =') - print >> f - if self.config.translation.gcrootfinder == "asmgcc": - write_list(ofiles, 'ASMFILES =') - write_list(gcmapfiles, 'GCMAPFILES =') - print >> f, 'OBJECTS = $(ASMFILES) gcmaptable.s' - else: - print >> f, 'GCMAPFILES =' - write_list(ofiles, 'OBJECTS =') - print >> f - def makerel(path): - rel = py.path.local(path).relto(py.path.local(autopath.pypydir)) - if rel: - return os.path.join('$(PYPYDIR)', rel) - else: - return path - args = ['-l'+libname for libname in self.eci.libraries] - print >> f, 'LIBS =', ' '.join(args) - args = ['-L'+makerel(path) for path in self.eci.library_dirs] - print >> f, 'LIBDIRS =', ' '.join(args) - args = ['-I'+makerel(path) for path in self.eci.include_dirs] - write_list(args, 'INCLUDEDIRS =') - print >> f - print >> f, 'CFLAGS =', ' '.join(compiler.compile_extra) - print >> f, 'LDFLAGS =', ' '.join(compiler.link_extra) - if self.config.translation.thread: - print >> f, 'TFLAGS = ' + '-pthread' - else: - print >> f, 'TFLAGS = ' + '' - print >> f, 'PROFOPT = ' + profopt - print >> f, 'MAKENOPROF = ' + make_no_prof - print >> f, 'CC = ' + cc - print >> f - print >> f, MAKEFILE.strip() - f.close() + rules = [ + ('clean', '', 'rm -f $(OBJECTS) $(TARGET) $(GCMAPFILES) *.gc?? ../module_cache/*.gc??'), + ('clean_noprof', '', 'rm -f $(OBJECTS) $(TARGET) $(GCMAPFILES)'), + ('debug', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT" $(TARGET)'), + ('debug_exc', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DDO_LOG_EXC" $(TARGET)'), + ('debug_mem', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DTRIVIAL_MALLOC_DEBUG" $(TARGET)'), + ('no_obmalloc', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DNO_OBMALLOC" $(TARGET)'), + ('linuxmemchk', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DLINUXMEMCHK" $(TARGET)'), + ('llsafer', '', '$(MAKE) CFLAGS="-O2 -DRPY_LL_ASSERT" $(TARGET)'), + ('lldebug', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DRPY_LL_ASSERT" $(TARGET)'), + ('profile', '', '$(MAKE) CFLAGS="-g -pg $(CFLAGS)" LDFLAGS="-pg $(LDFLAGS)" $(TARGET)'), + ('profopt', '', [ + '$(MAKENOPROF)', + '$(MAKE) CFLAGS="-fprofile-generate $(CFLAGS)" LDFLAGS="-fprofile-generate $(LDFLAGS)" $(TARGET)', + 'cd $(PYPYDIR)/translator/goal && $(ABS_TARGET) $(PROFOPT)', + '$(MAKE) clean_noprof', + '$(MAKE) CFLAGS="-fprofile-use $(CFLAGS)" LDFLAGS="-fprofile-use $(LDFLAGS)" $(TARGET)'])] + for rule in rules: + mk.rule(*rule) + + if self.config.translation.gcrootfinder == 'asmgcc': + ofiles = ['%s.s' % (cfile[:-2],) for cfile in mk.cfiles] + gcmapfiles = ['%s.gcmap' % (cfile[:-2],) for cfile in mk.cfiles] + mk.definition('ASMFILES', ofiles) + mk.definition('GCMAPFILES', gcmapfiles) + mk.definition('OBJECTS', '$(ASMFILES) gcmaptable.s') + mk.rule('%.s', '%.c', '$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS)') + mk.rule('%.gcmap', '%.s', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $@ || (rm -f $@ && exit 1)') + mk.rule('gcmaptable.s', '$(GCMAPFILES)', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@ || (rm -f $@ && exit 1)') + mk.write() + #self.translator.platform, + # , + # self.eci, profbased=self.getprofbased() + self.executable_name = mk.exe_name # ____________________________________________________________ @@ -889,99 +810,6 @@ gen_startupcode(f, database) f.close() - # - # Generate a setup.py while we're at it - # - pypy_include_dir = autopath.this_dir - f = targetdir.join('setup.py').open('w') - include_dirs = eci.include_dirs - library_dirs = eci.library_dirs - libraries = eci.libraries - f.write(SETUP_PY % locals()) - f.close() eci = eci.convert_sources_to_files(being_main=True) files, eci = eci.get_module_files() return eci, filename, sg.getextrafiles() + list(files) - -SETUP_PY = ''' -from distutils.core import setup -from distutils.extension import Extension -from distutils.ccompiler import get_default_compiler - -PYPY_INCLUDE_DIR = %(pypy_include_dir)r - -extra_compile_args = [] -if get_default_compiler() == "unix": - extra_compile_args.extend(["-Wno-unused-label", - "-Wno-unused-variable"]) - -setup(name="%(modulename)s", - ext_modules = [Extension(name = "%(modulename)s", - sources = ["%(modulename)s.c"], - extra_compile_args = extra_compile_args, - include_dirs = (PYPY_INCLUDE_DIR,) + %(include_dirs)r, - library_dirs = %(library_dirs)r, - libraries = %(libraries)r)]) -''' - -MAKEFILE = ''' - -all: $(DEFAULT_TARGET) - -$(TARGET): $(OBJECTS) -\t$(CC) $(LDFLAGS) $(TFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS) - -# -frandom-seed is only to try to be as reproducable as possible - -%.o: %.c -\t$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -c $< $(INCLUDEDIRS) - -%.s: %.c -\t$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS) - -%.gcmap: %.s -\t$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $@ || (rm -f $@ && exit 1) - -gcmaptable.s: $(GCMAPFILES) -\t$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@ || (rm -f $@ && exit 1) - -clean: -\trm -f $(OBJECTS) $(TARGET) $(GCMAPFILES) *.gc?? ../module_cache/*.gc?? - -clean_noprof: -\trm -f $(OBJECTS) $(TARGET) $(GCMAPFILES) - -debug: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT" $(TARGET) - -debug_exc: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DDO_LOG_EXC" $(TARGET) - -debug_mem: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DTRIVIAL_MALLOC_DEBUG" $(TARGET) - -no_obmalloc: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DNO_OBMALLOC" $(TARGET) - -linuxmemchk: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DLINUXMEMCHK" $(TARGET) - -llsafer: -\t$(MAKE) CFLAGS="-O2 -DRPY_LL_ASSERT" $(TARGET) - -lldebug: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DRPY_LL_ASSERT" $(TARGET) - -profile: -\t$(MAKE) CFLAGS="-g -pg $(CFLAGS)" LDFLAGS="-pg $(LDFLAGS)" $(TARGET) - -# it seems that GNU Make < 3.81 has no function $(abspath) -ABS_TARGET = $(shell python -c "import sys,os; print os.path.abspath(sys.argv[1])" $(TARGET)) - -profopt: -\t$(MAKENOPROF) # these files must be compiled without profiling -\t$(MAKE) CFLAGS="-fprofile-generate $(CFLAGS)" LDFLAGS="-fprofile-generate $(LDFLAGS)" $(TARGET) -\tcd $(PYPYDIR)/translator/goal && $(ABS_TARGET) $(PROFOPT) -\t$(MAKE) clean_noprof -\t$(MAKE) CFLAGS="-fprofile-use $(CFLAGS)" LDFLAGS="-fprofile-use $(LDFLAGS)" $(TARGET) -''' Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sun Oct 12 15:51:39 2008 @@ -214,6 +214,7 @@ rel_cfiles = [m.pathrel(cfile) for cfile in cfiles] rel_ofiles = [rel_cfile[:-2]+'.o' for rel_cfile in rel_cfiles] + m.cfiles = rel_cfiles rel_includedirs = [pypyrel(incldir) for incldir in eci.include_dirs] From fijal at codespeak.net Sun Oct 12 15:56:54 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 12 Oct 2008 15:56:54 +0200 (CEST) Subject: [pypy-svn] r59033 - pypy/branch/cbuild-refactor/pypy/translator/c Message-ID: <20081012135654.7D96116A257@codespeak.net> Author: fijal Date: Sun Oct 12 15:56:54 2008 New Revision: 59033 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Log: (fijal, pedronis) re-fix test_standalone in a saner manner Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Sun Oct 12 15:56:54 2008 @@ -379,6 +379,13 @@ bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) + def cmdexec(self, args=''): + assert self._compiled + res = self.translator.platform.execute(self.executable_name, args) + if res.returncode != 0: + raise Exception("Returned %d" % (res.returncode,)) + return res.out + def compile(self): assert self.c_source_filename assert not self._compiled From witulski at codespeak.net Sun Oct 12 16:26:36 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Sun, 12 Oct 2008 16:26:36 +0200 (CEST) Subject: [pypy-svn] r59034 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081012142636.B7AB316A1EC@codespeak.net> Author: witulski Date: Sun Oct 12 16:26:33 2008 New Revision: 59034 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: spilling implemented. - the args_gv of the label of enter_next_block are now copys (spilling could change refs) - gv_temp is removed from known_gv in allocate_register to avoid double entrys in that list - some comments added - move_back_to_register access the memory if the spilled gv is not the top of stack - allocate register uses spill_register when are no more free regs. left - stackdepth calc fixed - compares return refs of rax Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Sun Oct 12 16:26:33 2008 @@ -76,11 +76,11 @@ self.write(extra) self.write_modRM_byte(mod, modrm2, modrm1) elif isinstance(arg2.location, Stack64): - self.write_rex_byte(rexW, rexR, rexX, rexB) + self.write_rex_byte(rexW, rexB, rexX, rexR) self.write(opcode) # exchanged mod1,mod2, dont know why :) self.write_modRM_byte(mod, modrm1, modrm2) - # no scale, no index, base = rsp + # no scale(has no effect on rsp), no index, base = rsp self.write_SIB(0, 4, 4) self.writeImm32(arg2.location.offset) return quadreg_instr @@ -206,7 +206,7 @@ _IDIV_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xF7", 3, None, 7) _IMUL_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x0F", 3, None, None, None, "\xAF") - _IMUL_QWREG_IMM32 = make_two_operand_instr( 1, None, 0, None, "\x69", 3, None, "sameReg") + _IMUL_QWREG_IMM32 = make_two_operand_instr( 1, None, 0, None, "\x69", 3, None, "sameReg")#3 op instr _NEG_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xF7", 3, None, 3) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Sun Oct 12 16:26:33 2008 @@ -103,16 +103,16 @@ @specialize.arg(1) def genop1(self, opname, gv_arg): if isinstance(gv_arg, model.GenVar) and isinstance(gv_arg.location, Stack64): - move_back_to_register(gv_arg) + gv_arg = self.move_back_to_register(gv_arg) genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg) @specialize.arg(1) def genop2(self, opname, gv_arg1, gv_arg2): if isinstance(gv_arg1, model.GenVar) and isinstance(gv_arg1.location, Stack64): - move_back_to_register(gv_arg1) + gv_arg1 = self.move_back_to_register(gv_arg1) if isinstance(gv_arg2, model.GenVar) and isinstance(gv_arg2.location, Stack64): - move_back_to_register(gv_arg2) + gv_arg2 = self.move_back_to_register(gv_arg2) genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg1, gv_arg2) @@ -191,39 +191,40 @@ # TODO: use also rcx rdx gv_z = self.allocate_register("rax") self.mc.SETG(IntVar(Register8("al"))) - return IntVar(Register64("rax")) + return gv_z def op_int_lt(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETL(IntVar(Register8("al"))) - return IntVar(Register64("rax")) + return gv_z def op_int_le(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETLE(IntVar(Register8("al"))) - return IntVar(Register64("rax")) + return gv_z def op_int_eq(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETE(IntVar(Register8("al"))) - return IntVar(Register64("rax")) + return gv_z def op_int_ne(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETNE(IntVar(Register8("al"))) - return IntVar(Register64("rax")) + return gv_z def op_int_ge(self, gv_x, gv_y): self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETGE(IntVar(Register8("al"))) - return IntVar(Register64("rax")) + return gv_z # the moves to pass arg. when making a jump to a block + # the targetvars are only copys #FIXME: problem with mapping of stackpositions def _compute_moves(self, outputargs_gv, targetargs_gv): tar2src = {} @@ -260,8 +261,14 @@ def finish_and_return(self, sigtoken, gv_returnvar): #self.mc.write("\xB8\x0F\x00\x00\x00") self._open() + gv_return = self.allocate_register("rax") + # if there unused genVars on the stack + # pop them away + while not self.stackdepth == 0: + self.mc.POP(gv_return) + self.stackdepth = self.stackdepth -1 if not gv_returnvar == None:#check void return - self.mc.MOV(IntVar(Register64("rax")), gv_returnvar) + self.mc.MOV(gv_return, gv_returnvar) self.mc.RET() self._close() assert self.stackdepth == 0 @@ -281,29 +288,39 @@ self.mc.JMP(target.startaddr) self._close() + # FIXME: returns only ints + # FIXME: Double values in known_gv?? # TODO: support the allocation of 8bit Reg def allocate_register(self, register=None): if register is None: if not self.freeregisters: - #raise NotImplementedError("spilling not implemented") - return self.spill_register() + new_gv = self.spill_register() + self.known_gv.append(new_gv) + return new_gv + new_gv = IntVar(Register64(self.freeregisters.popitem()[0])) self.known_gv.append(new_gv) return new_gv + else: if register not in self.freeregisters: # the register must be in the list! for i in range(len(self.known_gv)): - if register == self.known_gv[i].location.reg: - # move the values from the requiered register - # to an other one and return the - # requested one. - gv = self.allocate_register() - self.mc.MOV(gv,self.known_gv[i]) + if isinstance(self.known_gv[i].location, Register64) and register == self.known_gv[i].location.reg: + # move the values from the requiered + # register to an other one and + # return the requested one. + gv_temp = self.allocate_register() + self.mc.MOV(gv_temp, self.known_gv[i]) new_gv = IntVar(Register64(register)) self.known_gv.append(new_gv) + self.known_gv[i].location.reg = gv_temp.location.reg + self.known_gv.remove(gv_temp) return new_gv - raise NotImplementedError("register moves") + + # raised when the register is not in freereg. and not + # used by a gen_var + raise Exception("error while register moves") del self.freeregisters[register] new_gv = IntVar(Register64(register)) self.known_gv.append(new_gv) @@ -312,15 +329,22 @@ def end(self): pass - #TODO: args_gv muste be a list of unique GenVars + # TODO: args_gv muste be a list of unique GenVars + # Spilling could change the location of a + # genVar after this Label. That will result in + # wrong a mapping in _compute_moves when leaving this block. + # So the parameters must be inmutable(copy them) def enter_next_block(self, args_gv): # move constants into an register + copy_args = [] for i in range(len(args_gv)): if isinstance(args_gv[i],model.GenConst): gv_x = self.allocate_register() self.mc.MOV(gv_x, args_gv[i]) args_gv[i] = gv_x - L = Label(self.mc.tell(), args_gv, 0) + # copy the gv + copy_args.append(IntVar(Register64(args_gv[i].location.reg))) + L = Label(self.mc.tell(), copy_args, 0) return L def _close(self): @@ -333,37 +357,44 @@ # take the first gv which is not # on the stack gv_to_spill = None - for i in range(len(known_gv)): - if not isinstance(known_gv[i].location, Stack64): + for i in range(len(self.known_gv)): + if not isinstance(self.known_gv[i].location, Stack64): gv_to_spill = self.known_gv[i] break # there must be genVars which are # inside an register so: assert isinstance(gv_to_spill.location, Register64) - self.stackdepth = self.stackdepth +1 self.mc.PUSH(gv_to_spill) new_gv = IntVar(Register64(gv_to_spill.location.reg)) - gv_to_spill.location = Stack64(self.stackdepth) + gv_to_spill.location = Stack64(self.stackdepth) return new_gv - def move_back_to_register(a_spilled_gv): - # if top of stack + # FIXME: pushed values are not allways poped (if not TOS) + def move_back_to_register(self, a_spilled_gv): + # if a_spilled_gv is the top of stack if a_spilled_gv.location.offset == self.stackdepth: gv_new = self.allocate_register() self.mc.POP(gv_new) self.stackdepth = self.stackdepth -1 assert self.stackdepth >= 0 #update all offsets - for i in range(len(known_gv)): - if isinstance(known_gv[i].location, Stack64): + for i in range(len(self.known_gv)): + if isinstance(self.known_gv[i].location, Stack64): known_gv[i].location.offset = known_gv[i].location.offset -1 a_spilled_gv = gv_new - # TODO: free gv_new (no double values in known_gv + # TODO: free gv_new (no double values in known_gv) + # TODO: look if there is a genVar with stackdepth + # if not it has already been moved to a reg. + # pop it or change the stackpointer + return a_spilled_gv + else: # else access the memory # FIXME: if this genVar becomes the top of stack it will never be pushed - else: - pass + gv_new = self.allocate_register() + self.mc.MOV(gv_new, IntVar(Stack64(8*(self.stackdepth-a_spilled_gv.location.offset)))) + a_spilled_gv = gv_new + return a_spilled_gv Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Sun Oct 12 16:26:33 2008 @@ -126,6 +126,15 @@ gv_result = builder.genop2(instr_name, gv_x, rgenop.genconst(num)) builder.finish_and_return(sigtoken, gv_result) builder.end() + return gv_op_imm + +def make_one_op_imm_instr_args_inv(rgenop, instr_name, num): + sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) + builder, gv_op_imm, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "one_op_imm_instr_args_inv") + builder.start_writing() + gv_result = builder.genop2(instr_name, rgenop.genconst(num), gv_x) + builder.finish_and_return(sigtoken, gv_result) + builder.end() return gv_op_imm class TestRGenopDirect(AbstractRGenOpTestsDirect): @@ -174,6 +183,14 @@ mul_function = make_one_op_imm_instr(rgenop, "int_mul", -9876) fnptr = self.cast(mul_function,1) res = fnptr(12345) + assert res == -121919220 + mul_function =make_one_op_imm_instr_args_inv(rgenop, "int_mul", 200) + fnptr = self.cast(mul_function,1) + res = fnptr(210) + assert res == 42000 + mul_function = make_one_op_imm_instr_args_inv(rgenop, "int_mul", -9876) + fnptr = self.cast(mul_function,1) + res = fnptr(12345) assert res == -121919220 def test_idiv_imm32(self): @@ -497,7 +514,7 @@ test_calling_pause_direct = skip test_longwinded_and_direct = skip test_condition_result_cross_link_direct = skip - test_multiple_cmps = skip + ##test_multiple_cmps = skip## test_flipped_cmp_with_immediate = skip test_jump_to_block_with_many_vars = skip test_same_as = skip From arigo at codespeak.net Sun Oct 12 17:02:30 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 17:02:30 +0200 (CEST) Subject: [pypy-svn] r59035 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081012150230.F00FD16A2A8@codespeak.net> Author: arigo Date: Sun Oct 12 17:02:30 2008 New Revision: 59035 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: (pedronis for a bit, arigo) Progress. One more test passes. That took the whole afternoon :-/ Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 17:02:30 2008 @@ -4,6 +4,7 @@ from pypy.translator.backendopt.support import log from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem.lloperation import llop # ____________________________________________________________ @@ -163,37 +164,6 @@ rtnodes, vtnodes = self.find_all_nodes() return vtnodes - def return_to_caller(self, retnode): - callerframe = self.callerframe - if callerframe is None: - raise ForcedInline("return block") - for i in range(len(callerframe.nodelist)): - if isinstance(callerframe.nodelist[i], FutureReturnValue): - callerframe.nodelist[i] = retnode - return callerframe - - def handle_raise(self, linkargsnodes): - if not is_trivial_nodelist(linkargsnodes): - raise CannotVirtualize("except block") - # ^^^ this could also be a ForcedInline, to try to match the - # exception raising and catching globally. But it looks - # overkill for now. - - # XXX this assumes no exception handler in the callerframes - topframe = self - while topframe.callerframe is not None: - topframe = topframe.callerframe - targetblock = topframe.sourcegraph.exceptblock - self.fixup_except_block(targetblock) - return topframe, targetblock - - def fixup_except_block(self, block): - # hack: this block's inputargs may be missing concretetypes... - e1, v1 = block.inputargs - e2, v2 = self.sourcegraph.exceptblock.inputargs - e1.concretetype = e2.concretetype - v1.concretetype = v2.concretetype - def copynodes(nodelist, flagreadonly={}): memo = {} @@ -225,8 +195,10 @@ class MallocVirtualizer(object): - def __init__(self, graphs, verbose=False): + def __init__(self, graphs, rtyper, verbose=False): self.graphs = graphs + self.rtyper = rtyper + self.excdata = rtyper.getexceptiondata() self.graphbuilders = {} self.specialized_graphs = {} self.inline_and_remove = {} # {graph: op_to_remove} @@ -279,6 +251,12 @@ if mode == 'fail': del self.specialized_graphs[key] + def fixup_except_block(self, exceptblock): + # hack: this block's inputargs may be missing concretetypes... + e1, v1 = exceptblock.inputargs + e1.concretetype = self.excdata.lltype_of_exception_type + v1.concretetype = self.excdata.lltype_of_exception_value + def getmalloctypedesc(self, MALLOCTYPE): try: dsc = self.malloctypedescs[MALLOCTYPE] @@ -399,6 +377,93 @@ srcblock.exitswitch = specblock.exitswitch srcblock.recloseblock(*specblock.exits) + def create_outgoing_link(self, currentframe, targetblock, + nodelist, renamings, v_expand_malloc=None): + assert len(nodelist) == len(targetblock.inputargs) + # + if is_except(targetblock): + v_expand_malloc = None + v_exc_type = renamings.get(nodelist[0]) + while currentframe.callerframe is not None: + currentframe = currentframe.callerframe + newlink = self.handle_catch(currentframe, v_exc_type, + renamings) + if newlink: + return newlink + else: + targetblock = self.exception_escapes(nodelist) + assert len(nodelist) == len(targetblock.inputargs) + + if (currentframe.callerframe is None and + is_trivial_nodelist(nodelist)): + # there is no more VirtualSpecNodes being passed around, + # so we can stop specializing + rtnodes = nodelist + specblock = targetblock + else: + if is_return(targetblock): + v_expand_malloc = None + newframe = self.return_to_caller(currentframe, nodelist[0]) + else: + targetnodes = dict(zip(targetblock.inputargs, nodelist)) + newframe = VirtualFrame(currentframe.sourcegraph, + targetblock, 0, targetnodes, + callerframe=currentframe.callerframe) + rtnodes = newframe.find_rt_nodes() + specblock = self.get_specialized_block(newframe, v_expand_malloc) + + linkargs = [renamings[rtnode] for rtnode in rtnodes] + return Link(linkargs, specblock) + + def return_to_caller(self, currentframe, retnode): + callerframe = currentframe.callerframe + if callerframe is None: + raise ForcedInline("return block") + for i in range(len(callerframe.nodelist)): + if isinstance(callerframe.nodelist[i], FutureReturnValue): + callerframe.nodelist[i] = retnode + return callerframe + + def handle_catch(self, catchingframe, v_exc_type, renamings): + if not self.has_exception_catching(catchingframe): + return None + if not isinstance(v_exc_type, Constant): + raise CannotVirtualize("raising non-constant exc type") + excdata = self.mallocv.excdata + assert catchingframe.sourceblock.exits[0].exitcase is None + for catchlink in catchingframe.sourceblock.exits[1:]: + if excdata.fn_exception_match(v_exc_type.value, + catchlink.llexitcase): + # Match found. Follow this link. + mynodes = catchingframe.get_nodes_in_use() + # XXX Constants + nodelist = [mynodes[v] for v in catchlink.args] + return self.create_outgoing_link(catchingframe, + catchlink.target, + nodelist, renamings) + else: + # No match at all, propagate the exception to the caller + return None + + def has_exception_catching(self, catchingframe): + if catchingframe.sourceblock.exitswitch != c_last_exception: + return False + else: + operations = catchingframe.sourceblock.operations + assert 1 <= catchingframe.nextopindex <= len(operations) + return catchingframe.nextopindex == len(operations) + + def exception_escapes(self, nodelist): + # the exception escapes + if not is_trivial_nodelist(nodelist): + raise CannotVirtualize("except block") + # ^^^ this could also be a ForcedInline, to try to match the + # exception raising and catching globally. But it looks + # overkill for now. + targetblock = self.graph.exceptblock + self.mallocv.fixup_except_block(targetblock) + return targetblock + def get_specialized_block(self, virtualframe, v_expand_malloc=None): key = virtualframe.getfrozenkey() specblock = self.specialized_blocks.get(key) @@ -448,7 +513,7 @@ if isinstance(v, Variable): return self.nodes[v] else: - rtnode = RuntimeSpecNode('const', v.concretetype) + rtnode = RuntimeSpecNode(None, v.concretetype) self.renamings[rtnode] = v return rtnode @@ -466,6 +531,7 @@ def specialize_operations(self): newoperations = [] + self.ops_produced_by_last_op = 0 # note that 'self.virtualframe' can be changed during the loop! while True: operations = self.virtualframe.sourceblock.operations @@ -477,18 +543,30 @@ meth = getattr(self, 'handle_op_' + op.opname, self.handle_default) - newoperations += meth(op) + newops_for_this_op = meth(op) + newoperations += newops_for_this_op + self.ops_produced_by_last_op = len(newops_for_this_op) self.specblock.operations = newoperations def follow_exits(self): block = self.virtualframe.sourceblock self.specblock.exitswitch = self.rename_nonvirtual(block.exitswitch, 'exitswitch') + links = block.exits catch_exc = self.specblock.exitswitch == c_last_exception + if catch_exc and self.ops_produced_by_last_op == 0: + # the last op of the sourceblock did not produce any + # operation in specblock, so we need to discard the + # exception-catching. + catch_exc = False + links = links[:1] + assert links[0].exitcase is None # the non-exception-catching case + self.specblock.exitswitch = None + newlinks = [] - for link in block.exits: - is_exc_link = catch_exc and link.exitcase is not None - if is_exc_link: + for link in links: + is_catch_link = catch_exc and link.exitcase is not None + if is_catch_link: extravars = [] for attr in ['last_exception', 'last_exc_value']: v = getattr(link, attr) @@ -498,44 +576,19 @@ self.renamings[rtnode] = v = rtnode.newvar() extravars.append(v) - currentframe = self.virtualframe linkargsnodes = [self.getnode(v1) for v1 in link.args] - targetblock = link.target - - if is_except(targetblock): - currentframe, targetblock = currentframe.handle_raise( - linkargsnodes) - - assert len(targetblock.inputargs) == len(linkargsnodes) - targetnodes = dict(zip(targetblock.inputargs, linkargsnodes)) - - if (currentframe.callerframe is None and - is_trivial_nodelist(linkargsnodes)): - # there is no more VirtualSpecNodes being passed around, - # so we can stop specializing - rtnodes = linkargsnodes - specblock = targetblock - else: - if is_return(targetblock): - newframe = currentframe.return_to_caller(linkargsnodes[0]) - v_expand_malloc = None - else: - newframe = VirtualFrame(currentframe.sourcegraph, - targetblock, 0, targetnodes, - callerframe=currentframe.callerframe) - v_expand_malloc = self.v_expand_malloc - rtnodes = newframe.find_rt_nodes() - specblock = self.graphbuilder.get_specialized_block(newframe, - v_expand_malloc) - - linkargs = [self.renamings[rtnode] for rtnode in rtnodes] - newlink = Link(linkargs, specblock) + # + newlink = self.graphbuilder.create_outgoing_link( + self.virtualframe, link.target, linkargsnodes, + self.renamings, self.v_expand_malloc) + # newlink.exitcase = link.exitcase if hasattr(link, 'llexitcase'): newlink.llexitcase = link.llexitcase - if is_exc_link: + if is_catch_link: newlink.extravars(*extravars) newlinks.append(newlink) + self.specblock.closeblock(*newlinks) def make_rt_result(self, v_result): @@ -545,10 +598,25 @@ self.renamings[newrtnode] = v_new return v_new + def make_const_rt_result(self, v_result, value): + newrtnode = RuntimeSpecNode(v_result, v_result.concretetype) + self.setnode(v_result, newrtnode) + if v_result.concretetype is not lltype.Void: + assert v_result.concretetype == lltype.typeOf(value) + c_value = Constant(value) + c_value.concretetype = v_result.concretetype + self.renamings[newrtnode] = c_value + def handle_default(self, op): newargs = [self.rename_nonvirtual(v, op) for v in op.args] - newresult = self.make_rt_result(op.result) - return [SpaceOperation(op.opname, newargs, newresult)] + constresult = try_fold_operation(op.opname, newargs, + op.result.concretetype) + if constresult: + self.make_const_rt_result(op.result, constresult[0]) + return [] + else: + newresult = self.make_rt_result(op.result) + return [SpaceOperation(op.opname, newargs, newresult)] def handle_unreachable(self, op): from pypy.rpython.lltypesystem.rstr import string_repr @@ -735,3 +803,30 @@ def is_except(block): return len(block.exits) == 0 and len(block.inputargs) == 2 + +class CannotConstFold(Exception): + pass + +def try_fold_operation(opname, args_v, RESTYPE): + args = [] + for c in args_v: + if not isinstance(c, Constant): + return + args.append(c.value) + try: + op = getattr(llop, opname) + except AttributeError: + return + if not op.is_pure(*[v.concretetype for v in args_v]): + return + try: + result = op(RESTYPE, *args) + except TypeError: + pass + except (KeyboardInterrupt, SystemExit): + raise + except Exception, e: + log.WARNING('constant-folding %s%r:' % (opname, args_v)) + log.WARNING(' %s: %s' % (e.__class__.__name__, e)) + else: + return (result,) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 17:02:30 2008 @@ -54,7 +54,7 @@ # to detect missing keepalives and broken intermediate graphs, # we do the loop ourselves instead of calling remove_simple_mallocs() maxiter = 100 - mallocv = MallocVirtualizer(t.graphs, verbose=True) + mallocv = MallocVirtualizer(t.graphs, t.rtyper, verbose=True) while True: progress = mallocv.remove_mallocs_once() #simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks())) @@ -273,7 +273,7 @@ self.check(f, [int], [-19], CHECK_RAISES("ValueError")) def test_call_raise_catch(self): - py.test.skip("in-progress") + #py.test.skip("in-progress") class A: pass def g(a): From antocuni at codespeak.net Sun Oct 12 17:12:39 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 12 Oct 2008 17:12:39 +0200 (CEST) Subject: [pypy-svn] r59036 - pypy/trunk/pypy/objspace/std/test Message-ID: <20081012151239.00F0B16A21F@codespeak.net> Author: antocuni Date: Sun Oct 12 17:12:36 2008 New Revision: 59036 Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Log: (antocuni, iko) write two failing tests for behaviour that changed from 2.4 to 2.5; it seems that we can't fix them, though :-( Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Sun Oct 12 17:12:36 2008 @@ -674,3 +674,31 @@ buf = buffer('character buffers are decoded to unicode') u = unicode(buf, 'utf-8', 'strict') assert u == u'character buffers are decoded to unicode' + + def test_formatting_unicode__str__(self): + skip('fixme!') + class A: + def __str__(self): + return u'\u1234' + + s = '%s' % A() + assert type(s) is unicode + assert s == u'\u1234' + + def test_formatting_unicode__str__2(self): + skip('XXX: do we really want to have such behaviour? CPython has not tests for that') + class A: + def __str__(self): + return u'baz' + + class B: + def __str__(self): + return 'foo' + + def __unicode__(self): + return u'bar' + + a = A() + b = B() + s = '%s %s' % (b, a) + assert s == u'foo baz' From arigo at codespeak.net Sun Oct 12 18:33:59 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 18:33:59 +0200 (CEST) Subject: [pypy-svn] r59039 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081012163359.A1DE3169DFC@codespeak.net> Author: arigo Date: Sun Oct 12 18:33:57 2008 New Revision: 59039 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: (pedronis, arigo) Add a test. Make the test fail in the right way, which took several backtrackings. We love our exception model! Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 18:33:57 2008 @@ -2,6 +2,7 @@ from pypy.objspace.flow.model import SpaceOperation, FunctionGraph, copygraph from pypy.objspace.flow.model import c_last_exception from pypy.translator.backendopt.support import log +from pypy.translator.unsimplify import varoftype from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import lltype from pypy.rpython.lltypesystem.lloperation import llop @@ -19,6 +20,7 @@ self.check_no_destructor() self.names_and_types = [] self.name2index = {} + self.name2subtype = {} self.initialize_type(MALLOCTYPE) #self.immutable_struct = MALLOCTYPE._hints.get('immutable') @@ -42,6 +44,7 @@ FIELDTYPE = TYPE._flds[name] self.name2index[name] = len(self.names_and_types) self.names_and_types.append((name, FIELDTYPE)) + self.name2subtype[name] = TYPE class SpecNode(object): @@ -206,6 +209,13 @@ self.malloctypedescs = {} self.count_virtualized = 0 self.verbose = verbose + self.EXCTYPE_to_vtable = self.build_obscure_mapping() + + def build_obscure_mapping(self): + result = {} + for rinstance in self.rtyper.instance_reprs.values(): + result[rinstance.lowleveltype.TO] = rinstance.rclass.getvtable() + return result def report_result(self): log.mallocv('removed %d mallocs so far' % (self.count_virtualized,)) @@ -383,15 +393,13 @@ # if is_except(targetblock): v_expand_malloc = None - v_exc_type = renamings.get(nodelist[0]) while currentframe.callerframe is not None: currentframe = currentframe.callerframe - newlink = self.handle_catch(currentframe, v_exc_type, - renamings) + newlink = self.handle_catch(currentframe, nodelist, renamings) if newlink: return newlink else: - targetblock = self.exception_escapes(nodelist) + targetblock = self.exception_escapes(nodelist, renamings) assert len(nodelist) == len(targetblock.inputargs) if (currentframe.callerframe is None and @@ -424,16 +432,22 @@ callerframe.nodelist[i] = retnode return callerframe - def handle_catch(self, catchingframe, v_exc_type, renamings): + def handle_catch(self, catchingframe, nodelist, renamings): if not self.has_exception_catching(catchingframe): return None - if not isinstance(v_exc_type, Constant): + [exc_node, exc_value_node] = nodelist + v_exc_type = renamings.get(exc_node) + if isinstance(v_exc_type, Constant): + exc_type = v_exc_type.value + elif isinstance(exc_value_node, VirtualSpecNode): + EXCTYPE = exc_value_node.typedesc.MALLOCTYPE + exc_type = self.mallocv.EXCTYPE_to_vtable[EXCTYPE] + else: raise CannotVirtualize("raising non-constant exc type") excdata = self.mallocv.excdata assert catchingframe.sourceblock.exits[0].exitcase is None for catchlink in catchingframe.sourceblock.exits[1:]: - if excdata.fn_exception_match(v_exc_type.value, - catchlink.llexitcase): + if excdata.fn_exception_match(exc_type, catchlink.llexitcase): # Match found. Follow this link. mynodes = catchingframe.get_nodes_in_use() # XXX Constants @@ -453,17 +467,79 @@ assert 1 <= catchingframe.nextopindex <= len(operations) return catchingframe.nextopindex == len(operations) - def exception_escapes(self, nodelist): + def exception_escapes(self, nodelist, renamings): # the exception escapes if not is_trivial_nodelist(nodelist): + # start of hacks to help handle_catch() + [exc_node, exc_value_node] = nodelist + v_exc_type = renamings.get(exc_node) + if isinstance(v_exc_type, Constant): + # cannot improve: handle_catch() would already be happy + # by seeing the exc_type as a constant + pass + elif isinstance(exc_value_node, VirtualSpecNode): + # can improve with a strange hack: we pretend that + # the source code jumps to a block that itself allocates + # the exception, sets all fields, and raises it by + # passing a constant type. + typedesc = exc_value_node.typedesc + return self.get_exc_reconstruction_block(typedesc) + else: + # cannot improve: handle_catch() will have no clue about + # the exception type + pass raise CannotVirtualize("except block") - # ^^^ this could also be a ForcedInline, to try to match the - # exception raising and catching globally. But it looks - # overkill for now. targetblock = self.graph.exceptblock self.mallocv.fixup_except_block(targetblock) return targetblock + def get_exc_reconstruction_block(self, typedesc): + exceptblock = self.graph.exceptblock + self.mallocv.fixup_except_block(exceptblock) + TEXC = exceptblock.inputargs[0].concretetype + TVAL = exceptblock.inputargs[1].concretetype + # + v_ignored_type = varoftype(TEXC) + v_incoming_value = varoftype(TVAL) + block = Block([v_ignored_type, v_incoming_value]) + # + c_EXCTYPE = Constant(typedesc.MALLOCTYPE, lltype.Void) + v = varoftype(lltype.Ptr(typedesc.MALLOCTYPE)) + c_flavor = Constant({'flavor': 'gc'}, lltype.Void) + op = SpaceOperation('malloc', [c_EXCTYPE, c_flavor], v) + block.operations.append(op) + # + for name, FIELDTYPE in typedesc.names_and_types: + EXACTPTR = lltype.Ptr(typedesc.name2subtype[name]) + c_name = Constant(name) + c_name.concretetype = lltype.Void + # + v_in = varoftype(EXACTPTR) + op = SpaceOperation('cast_pointer', [v_incoming_value], v_in) + block.operations.append(op) + # + v_field = varoftype(FIELDTYPE) + op = SpaceOperation('getfield', [v_in, c_name], v_field) + block.operations.append(op) + # + v_out = varoftype(EXACTPTR) + op = SpaceOperation('cast_pointer', [v], v_out) + block.operations.append(op) + # + v0 = Variable() + v0.concretetype = lltype.Void + op = SpaceOperation('setfield', [v_out, c_name, v_field], v0) + block.operations.append(op) + # + v_exc_value = varoftype(TVAL) + op = SpaceOperation('cast_pointer', [v], v_exc_value) + block.operations.append(op) + # + exc_type = self.mallocv.EXCTYPE_to_vtable[typedesc.MALLOCTYPE] + c_exc_type = Constant(exc_type, TEXC) + block.closeblock(Link([c_exc_type, v_exc_value], exceptblock)) + return block + def get_specialized_block(self, virtualframe, v_expand_malloc=None): key = virtualframe.getfrozenkey() specblock = self.specialized_blocks.get(key) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 18:33:57 2008 @@ -273,7 +273,6 @@ self.check(f, [int], [-19], CHECK_RAISES("ValueError")) def test_call_raise_catch(self): - #py.test.skip("in-progress") class A: pass def g(a): @@ -294,6 +293,28 @@ graph = self.check(f, [int], [11], 550, expected_calls=0) # inlined + def test_call_raise_catch_inspect(self): + py.test.skip("in-progress") + class A: + pass + class E(Exception): + def __init__(self, n): + self.n = n + def g(a): + a.n -= 1 + if a.n < 0: + raise E(a.n * 10) + def f(n): + a = A() + a.n = n + try: + g(a) # this call should be inlined + except E, e: + a.n = e.n + return a.n + self.check(f, [int], [15], 14, expected_calls=0) + self.check(f, [int], [-15], -160, expected_calls=0) + def test_fn2(self): class T: pass From arigo at codespeak.net Sun Oct 12 18:43:36 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 18:43:36 +0200 (CEST) Subject: [pypy-svn] r59040 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081012164336.5D5CD16A215@codespeak.net> Author: arigo Date: Sun Oct 12 18:43:35 2008 New Revision: 59040 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: (pedronis, arigo) Make the test pass. Exceptions are kind of working now :-) Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 18:43:35 2008 @@ -450,8 +450,19 @@ if excdata.fn_exception_match(exc_type, catchlink.llexitcase): # Match found. Follow this link. mynodes = catchingframe.get_nodes_in_use() - # XXX Constants - nodelist = [mynodes[v] for v in catchlink.args] + for node, attr in zip(nodelist, + ['last_exception', 'last_exc_value']): + v = getattr(catchlink, attr) + if isinstance(v, Variable): + mynodes[v] = node + # + nodelist = [] + for v in catchlink.args: + if isinstance(v, Variable): + node = mynodes[v] + else: + node = getconstnode(v, renamings) + nodelist.append(node) return self.create_outgoing_link(catchingframe, catchlink.target, nodelist, renamings) @@ -589,9 +600,7 @@ if isinstance(v, Variable): return self.nodes[v] else: - rtnode = RuntimeSpecNode(None, v.concretetype) - self.renamings[rtnode] = v - return rtnode + return getconstnode(v, self.renamings) def rename_nonvirtual(self, v, where=None): if not isinstance(v, Variable): @@ -906,3 +915,8 @@ log.WARNING(' %s: %s' % (e.__class__.__name__, e)) else: return (result,) + +def getconstnode(v, renamings): + rtnode = RuntimeSpecNode(None, v.concretetype) + renamings[rtnode] = v + return rtnode Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 18:43:35 2008 @@ -294,7 +294,6 @@ expected_calls=0) # inlined def test_call_raise_catch_inspect(self): - py.test.skip("in-progress") class A: pass class E(Exception): From arigo at codespeak.net Sun Oct 12 18:52:18 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 18:52:18 +0200 (CEST) Subject: [pypy-svn] r59041 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081012165218.2885D16A090@codespeak.net> Author: arigo Date: Sun Oct 12 18:52:17 2008 New Revision: 59041 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Port more tests. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 18:52:17 2008 @@ -42,6 +42,8 @@ fieldnames = fieldnames[1:] for name in fieldnames: FIELDTYPE = TYPE._flds[name] + if isinstance(FIELDTYPE, lltype.ContainerType): + raise CannotRemoveThisType("inlined substructure") self.name2index[name] = len(self.names_and_types) self.names_and_types.append((name, FIELDTYPE)) self.name2subtype[name] = TYPE Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 18:52:17 2008 @@ -430,38 +430,7 @@ return s*d self.check(fn1, [int, int], [15, 10], 125) - def test_dont_remove_with__del__(self): - py.test.skip("redo me") - import os - delcalls = [0] - class A(object): - nextid = 0 - def __init__(self): - self.id = self.nextid - self.nextid += 1 - - def __del__(self): - delcalls[0] += 1 - os.write(1, "__del__\n") - - def f(x=int): - a = A() - i = 0 - while i < x: - a = A() - os.write(1, str(delcalls[0]) + "\n") - i += 1 - return 1 - t = TranslationContext() - t.buildannotator().build_types(f, [int]) - t.buildrtyper().specialize() - graph = graphof(t, f) - backend_optimizations(t) - op = graph.startblock.exits[0].target.exits[1].target.operations[0] - assert op.opname == "malloc" - def test_add_keepalives(self): - py.test.skip("redo me") class A: pass SMALL = lltype.Struct('SMALL', ('x', lltype.Signed)) @@ -476,11 +445,10 @@ a.small.x += i i -= 1 return a.small.x - self.check(fn7, [int], [10], 55, must_be_removed=False) + self.check(fn7, [int], [10], 55, + expected_mallocs=1) # no support for interior structs def test_getsubstruct(self): - py.test.skip("redo me") - py.test.skip("fails because of the interior structure changes") SMALL = lltype.Struct('SMALL', ('x', lltype.Signed)) BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL)) @@ -490,11 +458,10 @@ b.s.x = n2 return b.z - b.s.x - self.check(fn, [int, int], [100, 58], 42) + self.check(fn, [int, int], [100, 58], 42, + expected_mallocs=1) # no support for interior structs def test_fixedsizearray(self): - py.test.skip("redo me") - py.test.skip("fails because of the interior structure changes") A = lltype.FixedSizeArray(lltype.Signed, 3) S = lltype.GcStruct('S', ('a', A)) @@ -505,7 +472,8 @@ a[2] = n2 return a[0]-a[2] - self.check(fn, [int, int], [100, 42], 58) + self.check(fn, [int, int], [100, 42], 58, + expected_mallocs=1) # no support for interior arrays def test_wrapper_cannot_be_removed(self): py.test.skip("redo me") From arigo at codespeak.net Sun Oct 12 19:03:36 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 19:03:36 +0200 (CEST) Subject: [pypy-svn] r59043 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081012170336.8132E16A298@codespeak.net> Author: arigo Date: Sun Oct 12 19:03:35 2008 New Revision: 59043 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Support for ptr_{nonzero,iszero,eq,ne}. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 19:03:35 2008 @@ -767,6 +767,42 @@ else: return self.handle_default(op) + def handle_op_ptr_nonzero(self, op): + node = self.getnode(op.args[0]) + if isinstance(node, VirtualSpecNode): + self.make_const_rt_result(op.result, True) + return [] + else: + return self.handle_default(op) + + def handle_op_ptr_iszero(self, op): + node = self.getnode(op.args[0]) + if isinstance(node, VirtualSpecNode): + self.make_const_rt_result(op.result, False) + return [] + else: + return self.handle_default(op) + + def handle_op_ptr_eq(self, op): + node0 = self.getnode(op.args[0]) + node1 = self.getnode(op.args[1]) + if (isinstance(node0, VirtualSpecNode) or + isinstance(node1, VirtualSpecNode)): + self.make_const_rt_result(op.result, node0 is node1) + return [] + else: + return self.handle_default(op) + + def handle_op_ptr_ne(self, op): + node0 = self.getnode(op.args[0]) + node1 = self.getnode(op.args[1]) + if (isinstance(node0, VirtualSpecNode) or + isinstance(node1, VirtualSpecNode)): + self.make_const_rt_result(op.result, node0 is not node1) + return [] + else: + return self.handle_default(op) + def handle_op_malloc(self, op): if op.result is self.v_expand_malloc: MALLOCTYPE = op.result.concretetype.TO Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 19:03:35 2008 @@ -8,7 +8,7 @@ from pypy.objspace.flow.model import checkgraph, flatten, Block, mkentrymap from pypy.objspace.flow.model import summary from pypy.rpython.llinterp import LLInterpreter, LLException -from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem import lltype, llmemory, lloperation from pypy.rpython.ootypesystem import ootype from pypy.rlib import objectmodel from pypy.rlib.rarithmetic import ovfcheck @@ -476,7 +476,6 @@ expected_mallocs=1) # no support for interior arrays def test_wrapper_cannot_be_removed(self): - py.test.skip("redo me") SMALL = lltype.OpaqueType('SMALL') BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL)) @@ -486,7 +485,9 @@ b = lltype.malloc(BIG) g(b.s) - self.check(fn, [], [], None, must_be_removed=False) + self.check(fn, [], [], None, + expected_mallocs=1, # no support for interior opaques + expected_calls=1) def test_direct_fieldptr(self): py.test.skip("redo me") @@ -533,12 +534,80 @@ self.check(fn, [], [], 12) def test_ptr_nonzero(self): - py.test.skip("redo me") S = lltype.GcStruct('S') def fn(): s = lltype.malloc(S) - return bool(s) - self.check(fn, [], [], True) + return lloperation.llop.ptr_nonzero(lltype.Bool, s) + self.check(fn, [], [], True, expected_mallocs=0) + + def test_ptr_iszero(self): + S = lltype.GcStruct('S') + def fn(): + s = lltype.malloc(S) + return lloperation.llop.ptr_iszero(lltype.Bool, s) + self.check(fn, [], [], False, expected_mallocs=0) + + def test_ptr_eq_null_left(self): + S = lltype.GcStruct('S') + def fn(): + s = lltype.malloc(S) + null = lltype.nullptr(S) + return lloperation.llop.ptr_eq(lltype.Bool, s, null) + self.check(fn, [], [], False, expected_mallocs=0) + + def test_ptr_ne_null_left(self): + S = lltype.GcStruct('S') + def fn(): + s = lltype.malloc(S) + null = lltype.nullptr(S) + return lloperation.llop.ptr_ne(lltype.Bool, s, null) + self.check(fn, [], [], True, expected_mallocs=0) + + def test_ptr_eq_null_right(self): + S = lltype.GcStruct('S') + def fn(): + s = lltype.malloc(S) + null = lltype.nullptr(S) + return lloperation.llop.ptr_eq(lltype.Bool, null, s) + self.check(fn, [], [], False, expected_mallocs=0) + + def test_ptr_ne_null_right(self): + S = lltype.GcStruct('S') + def fn(): + s = lltype.malloc(S) + null = lltype.nullptr(S) + return lloperation.llop.ptr_ne(lltype.Bool, null, s) + self.check(fn, [], [], True, expected_mallocs=0) + + def test_ptr_eq_same_struct(self): + S = lltype.GcStruct('S') + def fn(): + s1 = lltype.malloc(S) + return lloperation.llop.ptr_eq(lltype.Bool, s1, s1) + self.check(fn, [], [], True, expected_mallocs=0) + + def test_ptr_ne_same_struct(self): + S = lltype.GcStruct('S') + def fn(): + s1 = lltype.malloc(S) + return lloperation.llop.ptr_ne(lltype.Bool, s1, s1) + self.check(fn, [], [], False, expected_mallocs=0) + + def test_ptr_eq_diff_struct(self): + S = lltype.GcStruct('S') + def fn(): + s1 = lltype.malloc(S) + s2 = lltype.malloc(S) + return lloperation.llop.ptr_eq(lltype.Bool, s1, s2) + self.check(fn, [], [], False, expected_mallocs=0) + + def test_ptr_ne_diff_struct(self): + S = lltype.GcStruct('S') + def fn(): + s1 = lltype.malloc(S) + s2 = lltype.malloc(S) + return lloperation.llop.ptr_ne(lltype.Bool, s1, s2) + self.check(fn, [], [], True, expected_mallocs=0) def test_substruct_not_accessed(self): py.test.skip("redo me") From arigo at codespeak.net Sun Oct 12 19:10:31 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 19:10:31 +0200 (CEST) Subject: [pypy-svn] r59045 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081012171031.2C6F216A1DD@codespeak.net> Author: arigo Date: Sun Oct 12 19:10:30 2008 New Revision: 59045 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Test and fix. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Sun Oct 12 19:10:30 2008 @@ -539,8 +539,7 @@ op = SpaceOperation('cast_pointer', [v], v_out) block.operations.append(op) # - v0 = Variable() - v0.concretetype = lltype.Void + v0 = varoftype(lltype.Void) op = SpaceOperation('setfield', [v_out, c_name, v_field], v0) block.operations.append(op) # @@ -763,7 +762,16 @@ def handle_op_keepalive(self, op): node = self.getnode(op.args[0]) if isinstance(node, VirtualSpecNode): - return [] + rtnodes, vtnodes = find_all_nodes([node]) + newops = [] + for rtnode in rtnodes: + v = self.renamings[rtnode] + if isinstance(v, Variable): + T = v.concretetype + if isinstance(T, lltype.Ptr) and T._needsgc(): + v0 = varoftype(lltype.Void) + newops.append(SpaceOperation('keepalive', [v], v0)) + return newops else: return self.handle_default(op) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 19:10:30 2008 @@ -634,7 +634,6 @@ self.check(fn, [], [], DONT_CHECK_RESULT) def test_keep_all_keepalives(self): - py.test.skip("redo me") SIZE = llmemory.sizeof(lltype.Signed) PARRAY = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1)) class A: @@ -657,7 +656,8 @@ objectmodel.keepalive_until_here(b) return res graph = self.check(myfunc, [], [], 42, - must_be_removed=False) # 'A' instance left + expected_mallocs=1, # 'A' instance left + expected_calls=1) # to A.__init__() # there is a getarrayitem near the end of the graph of myfunc. # However, the memory it accesses must still be protected by the From arigo at codespeak.net Sun Oct 12 19:12:06 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 12 Oct 2008 19:12:06 +0200 (CEST) Subject: [pypy-svn] r59046 - pypy/dist/pypy/translator/backendopt/test Message-ID: <20081012171206.A373C16A1DD@codespeak.net> Author: arigo Date: Sun Oct 12 19:12:04 2008 New Revision: 59046 Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: One more test passes. Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Sun Oct 12 19:12:04 2008 @@ -667,7 +667,6 @@ assert link.prevblock.operations[-1].opname == 'keepalive' def test_nested_struct(self): - py.test.skip("redo me") S = lltype.GcStruct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('s', S)) def f(x): @@ -680,7 +679,6 @@ def test_interior_ptr(self): py.test.skip("redo me") - py.test.skip("fails") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('s', S)) def f(x): From fijal at codespeak.net Mon Oct 13 09:29:41 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 09:29:41 +0200 (CEST) Subject: [pypy-svn] r59052 - pypy/branch/cbuild-refactor/pypy/config/test Message-ID: <20081013072941.0D44616A00A@codespeak.net> Author: fijal Date: Mon Oct 13 09:29:38 2008 New Revision: 59052 Modified: pypy/branch/cbuild-refactor/pypy/config/test/test_pypyoption.py Log: Fix the test. Modified: pypy/branch/cbuild-refactor/pypy/config/test/test_pypyoption.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/config/test/test_pypyoption.py (original) +++ pypy/branch/cbuild-refactor/pypy/config/test/test_pypyoption.py Mon Oct 13 09:29:38 2008 @@ -41,7 +41,7 @@ assert not conf.translation.backendopt.none conf = get_pypy_config() set_opt_level(conf, 'mem') - assert conf.translation.gc == 'marksweep' + assert conf.translation.gc == 'markcompact' assert not conf.translation.backendopt.none def test_set_pypy_opt_level(): From fijal at codespeak.net Mon Oct 13 09:34:24 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 09:34:24 +0200 (CEST) Subject: [pypy-svn] r59053 - pypy/branch/cbuild-refactor/pypy/module/_rawffi/test Message-ID: <20081013073424.4A0E8169F4F@codespeak.net> Author: fijal Date: Mon Oct 13 09:34:23 2008 New Revision: 59053 Modified: pypy/branch/cbuild-refactor/pypy/module/_rawffi/test/test__rawffi.py Log: Fix those tests Modified: pypy/branch/cbuild-refactor/pypy/module/_rawffi/test/test__rawffi.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/module/_rawffi/test/test__rawffi.py (original) +++ pypy/branch/cbuild-refactor/pypy/module/_rawffi/test/test__rawffi.py Mon Oct 13 09:34:23 2008 @@ -5,6 +5,7 @@ ExternalCompilationInfo from pypy.module._rawffi.interp_rawffi import TYPEMAP from pypy.module._rawffi.tracker import Tracker +from pypy.translator.platform import platform import os, sys, py @@ -154,7 +155,7 @@ give perturb """.split() eci = ExternalCompilationInfo(export_symbols=symbols) - return compile_c_module([c_file], 'x', eci) + return str(platform.compile([c_file], eci, 'x', standalone=False)) prepare_c_example = staticmethod(prepare_c_example) def setup_class(cls): From fijal at codespeak.net Mon Oct 13 10:02:23 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 10:02:23 +0200 (CEST) Subject: [pypy-svn] r59054 - pypy/branch/cbuild-refactor/pypy/translator/tool Message-ID: <20081013080223.ED76516A04E@codespeak.net> Author: fijal Date: Mon Oct 13 10:02:23 2008 New Revision: 59054 Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Log: Try a bit harder to get a bit more unique name. Fixes some tests Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Mon Oct 13 10:02:23 2008 @@ -265,7 +265,14 @@ self = self.convert_sources_to_files() if not self.separate_module_files: return self - lib = str(host.compile([], self, outputfilename='externmod', + # find more or less unique name there + basepath = py.path.local(self.separate_module_files[0]).dirpath() + pth = basepath.join('externmod').new(ext=host.so_ext) + num = 0 + while pth.check(): + pth = basepath.join('externmod_%d' % (num,)).new(ext=host.so_ext) + num += 1 + lib = str(host.compile([], self, outputfilename=pth.purebasename, standalone=False)) d = self._copy_attributes() d['libraries'] += (lib,) From fijal at codespeak.net Mon Oct 13 10:09:05 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 10:09:05 +0200 (CEST) Subject: [pypy-svn] r59055 - pypy/branch/cbuild-refactor/pypy/translator/c/src Message-ID: <20081013080905.D0354169E09@codespeak.net> Author: fijal Date: Mon Oct 13 10:09:05 2008 New Revision: 59055 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/src/signals.h Log: including the whole python.h for couple of constants seems to make little sense, try to be a bit smarter. Modified: pypy/branch/cbuild-refactor/pypy/translator/c/src/signals.h ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/src/signals.h (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/src/signals.h Mon Oct 13 10:09:05 2008 @@ -4,7 +4,21 @@ #ifndef _PYPY_SIGNALS_H #define _PYPY_SIGNALS_H -#include "Python.h" /* XXX for LONG_MIN */ +#include + +#ifndef LONG_MAX +#if SIZEOF_LONG == 4 +#define LONG_MAX 0X7FFFFFFFL +#elif SIZEOF_LONG == 8 +#define LONG_MAX 0X7FFFFFFFFFFFFFFFL +#else +#error "could not set LONG_MAX in pyport.h" +#endif +#endif + +#ifndef LONG_MIN +#define LONG_MIN (-LONG_MAX-1) +#endif #include From fijal at codespeak.net Mon Oct 13 10:13:53 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 10:13:53 +0200 (CEST) Subject: [pypy-svn] r59056 - pypy/branch/cbuild-refactor/pypy/rpython/module Message-ID: <20081013081353.9704A169E14@codespeak.net> Author: fijal Date: Mon Oct 13 10:13:53 2008 New Revision: 59056 Modified: pypy/branch/cbuild-refactor/pypy/rpython/module/ll_strtod.py Log: We don't include pypy directory by default. Let's make it explicit Modified: pypy/branch/cbuild-refactor/pypy/rpython/module/ll_strtod.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/rpython/module/ll_strtod.py (original) +++ pypy/branch/cbuild-refactor/pypy/rpython/module/ll_strtod.py Mon Oct 13 10:13:53 2008 @@ -7,10 +7,12 @@ from pypy.rpython.ootypesystem import ootype from pypy.rlib import rposix from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.tool.autopath import pypydir class CConfig: _compilation_info_ = ExternalCompilationInfo( includes = ['src/ll_strtod.h'], + include_dirs = [str(py.path.local(pypydir).join('translator', 'c'))], separate_module_sources = ['#include '], export_symbols = ['LL_strtod_formatd', 'LL_strtod_parts_to_float'], ) From fijal at codespeak.net Mon Oct 13 10:33:48 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 10:33:48 +0200 (CEST) Subject: [pypy-svn] r59057 - pypy/branch/cbuild-refactor/pypy/rpython/tool Message-ID: <20081013083348.58F1A16A08F@codespeak.net> Author: fijal Date: Mon Oct 13 10:33:46 2008 New Revision: 59057 Modified: pypy/branch/cbuild-refactor/pypy/rpython/tool/rffi_platform.py Log: * Catch correct CompilationError * Don't force list of files here Modified: pypy/branch/cbuild-refactor/pypy/rpython/tool/rffi_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/rpython/tool/rffi_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/rpython/tool/rffi_platform.py Mon Oct 13 10:33:46 2008 @@ -6,7 +6,7 @@ from pypy.rpython.lltypesystem import llmemory from pypy.tool.gcc_cache import build_executable_cache, try_compile_cache from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.translator.tool.cbuild import CompilationError +from pypy.translator.platform import CompilationError from pypy.tool.udir import udir import distutils @@ -538,7 +538,7 @@ def run_example_code(filepath, eci): eci = eci.convert_sources_to_files(being_main=True) - files = [filepath] + [py.path.local(f) for f in eci.separate_module_files] + files = [filepath] output = build_executable_cache(files, eci) section = None for line in output.splitlines(): From fijal at codespeak.net Mon Oct 13 10:40:41 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 10:40:41 +0200 (CEST) Subject: [pypy-svn] r59058 - pypy/branch/cbuild-refactor/pypy Message-ID: <20081013084041.AAE61169E14@codespeak.net> Author: fijal Date: Mon Oct 13 10:40:41 2008 New Revision: 59058 Added: pypy/branch/cbuild-refactor/pypy/TODO.beformerge Log: what todo before merge Added: pypy/branch/cbuild-refactor/pypy/TODO.beformerge ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/TODO.beformerge Mon Oct 13 10:40:41 2008 @@ -0,0 +1,3 @@ +* Move distutils support into distutils platform +* Make sure ctypes_configure is working +* Check why socket test is hanging (and if it's handing on dist/trunk as well) \ No newline at end of file From fijal at codespeak.net Mon Oct 13 10:43:25 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 10:43:25 +0200 (CEST) Subject: [pypy-svn] r59059 - pypy/branch/cbuild-refactor/pypy/rlib/test Message-ID: <20081013084325.426A316A0B1@codespeak.net> Author: fijal Date: Mon Oct 13 10:43:24 2008 New Revision: 59059 Modified: pypy/branch/cbuild-refactor/pypy/rlib/test/test_libffi.py Log: A bit of str() Modified: pypy/branch/cbuild-refactor/pypy/rlib/test/test_libffi.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/rlib/test/test_libffi.py (original) +++ pypy/branch/cbuild-refactor/pypy/rlib/test/test_libffi.py Mon Oct 13 10:43:24 2008 @@ -229,8 +229,8 @@ lltype.free(tp, flavor='raw') def test_struct_by_val(self): - from pypy.translator.tool.cbuild import compile_c_module, \ - ExternalCompilationInfo + from pypy.translator.tool.cbuild import ExternalCompilationInfo + from pypy.translator.platform import platform from pypy.tool.udir import udir c_file = udir.ensure("test_libffi", dir=1).join("xlib.c") @@ -253,7 +253,7 @@ ''')) eci = ExternalCompilationInfo(export_symbols=['sum_x_y']) - lib_name = compile_c_module([c_file], 'x', eci) + lib_name = str(platform.compile([c_file], eci, 'x', standalone=False)) lib = CDLL(lib_name) @@ -280,8 +280,8 @@ assert not ALLOCATED def test_ret_struct_val(self): - from pypy.translator.tool.cbuild import compile_c_module, \ - ExternalCompilationInfo + from pypy.translator.tool.cbuild import ExternalCompilationInfo + from pypy.translator.platform import platform from pypy.tool.udir import udir c_file = udir.ensure("test_libffi", dir=1).join("xlib.c") @@ -309,7 +309,7 @@ ''')) eci = ExternalCompilationInfo(export_symbols=['give', 'perturb']) - lib_name = compile_c_module([c_file], 'x', eci) + lib_name = str(platform.compile([c_file], eci, 'x', standalone=False)) lib = CDLL(lib_name) From fijal at codespeak.net Mon Oct 13 10:44:51 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 10:44:51 +0200 (CEST) Subject: [pypy-svn] r59060 - pypy/branch/cbuild-refactor/pypy/annotation Message-ID: <20081013084451.1255D16A0EC@codespeak.net> Author: fijal Date: Mon Oct 13 10:44:50 2008 New Revision: 59060 Modified: pypy/branch/cbuild-refactor/pypy/annotation/model.py Log: Turn off overloaded info by default Modified: pypy/branch/cbuild-refactor/pypy/annotation/model.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/annotation/model.py (original) +++ pypy/branch/cbuild-refactor/pypy/annotation/model.py Mon Oct 13 10:44:50 2008 @@ -37,7 +37,7 @@ from pypy.rlib.rarithmetic import r_singlefloat import inspect, weakref -DEBUG = True # set to False to disable recording of debugging information +DEBUG = False # set to False to disable recording of debugging information TLS = tlsobject() class SomeObject: From fijal at codespeak.net Mon Oct 13 10:45:38 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 10:45:38 +0200 (CEST) Subject: [pypy-svn] r59061 - in pypy/branch/cbuild-refactor/pypy/translator: platform sandbox/test Message-ID: <20081013084538.C616216A153@codespeak.net> Author: fijal Date: Mon Oct 13 10:45:38 2008 New Revision: 59061 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_pypy_interact.py pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_sandbox.py pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_sandlib.py Log: Fix tests Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Mon Oct 13 10:45:38 2008 @@ -110,6 +110,7 @@ class Linux(Platform): link_flags = ['-pthread'] cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] + so_ext = 'so' def __init__(self, cc=None): if cc is None: @@ -147,7 +148,7 @@ exe_name = py.path.local(os.path.join(str(cfiles[0].dirpath()), outputfilename)) if not standalone: - exe_name += '.so' + exe_name += '.' + self.so_ext ofiles = [] for cfile in cfiles: ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) Modified: pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_pypy_interact.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_pypy_interact.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_pypy_interact.py Mon Oct 13 10:45:38 2008 @@ -66,7 +66,7 @@ def setup_module(mod): t = Translation(mini_pypy_like_entry_point, backend='c', standalone=True, sandbox=True) - mod.executable = t.compile() + mod.executable = str(t.compile()) def test_run(): Modified: pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_sandbox.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_sandbox.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_sandbox.py Mon Oct 13 10:45:38 2008 @@ -29,7 +29,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_os.ll_os_open", ("/tmp/foobar", os.O_RDONLY, 0777), 77) expect(f, g, "ll_os.ll_os_dup", (77,), 78) @@ -50,7 +50,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_os.ll_os_open", ("/tmp/foobar", os.O_RDONLY, 0777), 77) expect(f, g, "ll_os.ll_os_read", (77, 123), "he\x00llo") @@ -68,7 +68,7 @@ return 1 - y t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_os.ll_os_dup2", (34, 56), None) expect(f, g, "ll_os.ll_os_access", ("spam", 77), True) @@ -88,7 +88,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) st = os.stat_result((55, 0, 0, 0, 0, 0, 0x12380000007, 0, 0, 0)) expect(f, g, "ll_os.ll_os_stat", ("somewhere",), st, @@ -106,7 +106,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_time.ll_time_time", (), 3.141592) expect(f, g, "ll_os.ll_os_dup", (3141,), 3) @@ -124,7 +124,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_os.ll_os_stat", ("somewhere",), OSError(6321, "egg")) expect(f, g, "ll_os.ll_os_close", (6321,), None) @@ -138,7 +138,7 @@ def run(self, entry_point, args, expected): t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) from pypy.translator.sandbox.sandlib import SimpleIOSandboxedProc proc = SimpleIOSandboxedProc([exe] + args) output, error = proc.communicate() Modified: pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_sandlib.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_sandlib.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/sandbox/test/test_sandlib.py Mon Oct 13 10:45:38 2008 @@ -47,7 +47,7 @@ os.close(fd) return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = MySandboxedProc([exe, 'x1', 'y2'], expected = [ ("open", ("/tmp/foobar", os.O_RDONLY, 0777), 77), @@ -69,7 +69,7 @@ s = rffi.str2charp(argv[n]); n = foobar(s); rffi.free_charp(s) return n t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = MySandboxedProc([exe, 'spam', 'egg'], expected = [ ("foobar", ("spam",), 2), @@ -93,7 +93,7 @@ print "The double is:", num * 2 return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = SimpleIOSandboxedProc([exe, 'x1', 'y2']) output, error = proc.communicate("21\n") @@ -111,7 +111,7 @@ print os.read(fd, 30) return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = SocketProc([exe]) output, error = proc.communicate("") @@ -125,7 +125,7 @@ os.close(e.errno) # nonsense, just to see outside return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = MySandboxedProc([exe], expected = [ ("open", ("/tmp/foobar", os.O_RDONLY, 0777), OSError(-42, "baz")), From iko at codespeak.net Mon Oct 13 10:46:45 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Mon, 13 Oct 2008 10:46:45 +0200 (CEST) Subject: [pypy-svn] r59062 - pypy/dist/pypy/translator/goal Message-ID: <20081013084645.8646816A188@codespeak.net> Author: iko Date: Mon Oct 13 10:46:45 2008 New Revision: 59062 Added: pypy/dist/pypy/translator/goal/targettestdicts.py (contents, props changed) pypy/dist/pypy/translator/goal/targettestlistvsdict.py (contents, props changed) Log: (iko,pedronis) Some test food for static data info. These generate insane results: for targettestdicts.py, only the size of the dicts are counted, not the contained strings (so the result is too small). for targettestlistvsdict.py, the list only seems to count the size of the contained strings, not the size of the array. The dict is counted (correctly? since the same strings are in the list) as the size of its structure. Added: pypy/dist/pypy/translator/goal/targettestdicts.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/goal/targettestdicts.py Mon Oct 13 10:46:45 2008 @@ -0,0 +1,30 @@ +""" +A simple standalone target. + +The target below specifies None as the argument types list. +This is a case treated specially in driver.py . If the list +of input types is empty, it is meant to be a list of strings, +actually implementing argv of the executable. +""" + +import os, sys + +def debug(msg): + os.write(2, "debug: " + msg + '\n') + +# __________ Entry point __________ + +test_dict = dict(map(lambda x: (x, hex(x)), range(5000))) +reverse_dict = dict(map(lambda (x,y): (y,x), test_dict.items())) + +def entry_point(argv): + if argv[1] == 'd': + print test_dict[int(argv[2])] + else: + print reverse_dict[argv[2]] + return 0 + +# _____ Define and setup target ___ + +def target(*args): + return entry_point, None Added: pypy/dist/pypy/translator/goal/targettestlistvsdict.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/goal/targettestlistvsdict.py Mon Oct 13 10:46:45 2008 @@ -0,0 +1,30 @@ +""" +A simple standalone target. + +The target below specifies None as the argument types list. +This is a case treated specially in driver.py . If the list +of input types is empty, it is meant to be a list of strings, +actually implementing argv of the executable. +""" + +import os, sys + +def debug(msg): + os.write(2, "debug: " + msg + '\n') + +# __________ Entry point __________ + +test_list = map(hex, range(5000)) +test_dict = dict(map(lambda x: (x, hex(x)), range(5000))) + +def entry_point(argv): + if argv[1] == 'd': + print test_dict[int(argv[2])] + else: + print test_list[int(argv[2])] + return 0 + +# _____ Define and setup target ___ + +def target(*args): + return entry_point, None From iko at codespeak.net Mon Oct 13 10:54:00 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Mon, 13 Oct 2008 10:54:00 +0200 (CEST) Subject: [pypy-svn] r59063 - pypy/dist/pypy/module/unicodedata Message-ID: <20081013085400.D5EE616A261@codespeak.net> Author: iko Date: Mon Oct 13 10:54:00 2008 New Revision: 59063 Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Log: some improvements for selecting the list sizes Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/generate_unicodedb.py (original) +++ pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Mon Oct 13 10:54:00 2008 @@ -333,7 +333,7 @@ for i in range(1,len(ranges)): lows, lowe = collapsed[-1] highs, highe = ranges[i] - if highs - lowe < max([lowe - lows, highe - highs]): + if highs - lowe < 8: collapsed[-1] = (lows, highe) else: collapsed.append(ranges[i]) @@ -354,6 +354,19 @@ " from pypy.module.unicodedata import compression", " res = None"] for low, high in ranges: + if high - low <= 5: + # Too short for list + for code in range(low, high + 1): + name = table[code].name + if name: + function.append( + " if code == %d: res = %r" % ( + code, compression.compress(codelist, name))) + f_reverse_dict.append( + " res[%r] = %d" % ( + compression.compress(codelist, name), code)) + continue + function.append( " if %d <= code <= %d: res = _charnames_%d[code-%d]" % ( low, high, low, low)) From cami at codespeak.net Mon Oct 13 11:41:25 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Mon, 13 Oct 2008 11:41:25 +0200 (CEST) Subject: [pypy-svn] r59064 - pypy/dist/pypy/lang/gameboy/debug Message-ID: <20081013094125.CD9EB16A0A6@codespeak.net> Author: cami Date: Mon Oct 13 11:41:23 2008 New Revision: 59064 Modified: pypy/dist/pypy/lang/gameboy/debug/debug.py pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py Log: debuger prints now the function names Modified: pypy/dist/pypy/lang/gameboy/debug/debug.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/debug.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/debug.py Mon Oct 13 11:41:23 2008 @@ -1,4 +1,6 @@ import operator +from pypy.lang.gameboy import cpu +import pdb DEBUG = True DEBUG_PRINT_LOGS = True @@ -86,16 +88,17 @@ CHECKED_OP_CODES = [0x00] CHECKED_FETCH_OP_CODES = [] +BAR_WIDTH = 79 def log(opCode, is_fetch_execute=False): global COUNT, op_codes, fetch_execute_op_codes if DEBUG_PRINT_LOGS: - print "="*40 + print "=" * BAR_WIDTH if is_fetch_execute: - print COUNT[0], " FETCH EXEC: %i | %s" % (opCode, hex(opCode)) + print COUNT[0], " FETCH EXEC: %i | %s | %s" % (opCode, hex(opCode), resolve_fetch_opcode_name(opCode)) else: - print COUNT[0], " EXEC: %i | %s" % (opCode, hex(opCode)) - print "-"*40 + print COUNT[0], " EXEC: %i | %s | %s" % (opCode, hex(opCode), resolve_opcode_name(opCode)) + print "-" * BAR_WIDTH if is_fetch_execute: fetch_execute_op_codes[opCode ]+= 1 @@ -105,7 +108,27 @@ #if COUNT % 1000 == 0: # print "." - +def resolve_opcode_name(opcode): + method = cpu.OP_CODES[opcode].__name__ + if method == "": + try: + functions = "[ " + for func_closure in cpu.OP_CODES[opcode].func_closure: + functions += func_closure.cell_contents.im_func.__name__+ ", "; + return functions + "]"; + except: + return cpu.OP_CODES[opcode].func_code.co_names; + else: + return method; + +def resolve_fetch_opcode_name(opcode): + method = cpu.OP_CODES[opcode].__name__ + if method == "": + pdb.set_trace() + else: + return method; + + def print_results(): global COUNT, op_codes, fetch_execute_op_codes Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_entry_point.py Mon Oct 13 11:41:23 2008 @@ -53,11 +53,12 @@ JMARIO_DIR = str(py.magic.autopath().dirpath().dirpath()\ .dirpath().dirpath()\ .dirpath().dirpath()) + "/jmario" -JAVA_CLASSPATH =[JMARIO_DIR+"/bin/", JMARIO_DIR+"/build/", - JMARIO_DIR+"/lib/xmlrpc-client-3.1.jar", - JMARIO_DIR+"/lib/xmlrpc-common-3.1.jar", - JMARIO_DIR+"/lib/ws-commons-util-1.0.2.jar", - JMARIO_DIR+"/lib/commons-logging-1.1.jar"]; + +JAVA_CLASSPATH =[ JMARIO_DIR + "/bin/", JMARIO_DIR+"/build/", + JMARIO_DIR + "/lib/xmlrpc-client-3.1.jar", + JMARIO_DIR + "/lib/xmlrpc-common-3.1.jar", + JMARIO_DIR + "/lib/ws-commons-util-1.0.2.jar", + JMARIO_DIR + "/lib/commons-logging-1.1.jar"]; def start_java_version(): global filename @@ -77,7 +78,7 @@ # START ======================================================================== parse_file_name() -threading.Timer(1, start_java_version).start() -threading.Timer(0.001, start_python_version()).start() +threading.Timer(1, start_java_version ).start() +threading.Timer(0, start_python_version()).start() Modified: pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/gameboy_debug_implementation.py Mon Oct 13 11:41:23 2008 @@ -32,7 +32,6 @@ self.emulate(constants.GAMEBOY_CLOCK >> 2) def handle_execution_error(self, error): - GameBoyImplementation.handle_execution_error(self, error) print error print "closing socket connections" pdb.set_trace() From arigo at codespeak.net Mon Oct 13 13:41:27 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 13 Oct 2008 13:41:27 +0200 (CEST) Subject: [pypy-svn] r59065 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081013114127.6396E16A301@codespeak.net> Author: arigo Date: Mon Oct 13 13:41:25 2008 New Revision: 59065 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Test and fix for functions with unused arguments. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Mon Oct 13 13:41:25 2008 @@ -2,12 +2,21 @@ from pypy.objspace.flow.model import SpaceOperation, FunctionGraph, copygraph from pypy.objspace.flow.model import c_last_exception from pypy.translator.backendopt.support import log +from pypy.translator.simplify import join_blocks from pypy.translator.unsimplify import varoftype from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import lltype from pypy.rpython.lltypesystem.lloperation import llop +def virtualize_mallocs(translator, verbose=True): + mallocv = MallocVirtualizer(translator.graphs, translator.rtyper, verbose) + while mallocv.remove_mallocs_once(): + pass + translator.checkgraphs() + for graph in translator.graphs: + join_blocks(graph) + # ____________________________________________________________ @@ -113,8 +122,13 @@ def __init__(self, sourcegraph, sourceblock, nextopindex, allnodes, callerframe=None): - self.varlist = vars_alive_through_op(sourceblock, nextopindex) - self.nodelist = [allnodes[v] for v in self.varlist] + if isinstance(allnodes, dict): + self.varlist = vars_alive_through_op(sourceblock, nextopindex) + self.nodelist = [allnodes[v] for v in self.varlist] + else: + assert nextopindex == 0 + self.varlist = sourceblock.inputargs + self.nodelist = allnodes[:] self.sourcegraph = sourcegraph self.sourceblock = sourceblock self.nextopindex = nextopindex @@ -219,9 +233,11 @@ result[rinstance.lowleveltype.TO] = rinstance.rclass.getvtable() return result - def report_result(self): - log.mallocv('removed %d mallocs so far' % (self.count_virtualized,)) - return self.count_virtualized + def report_result(self, progress): + if progress: + log.mallocv('removed %d mallocs so far' % self.count_virtualized) + else: + log.mallocv('done') def enum_all_mallocs(self, graph): for block in graph.iterblocks(): @@ -254,9 +270,11 @@ break # graph mutated, restart enum_all_mallocs() else: break # enum_all_mallocs() exhausted, graph finished - progress1 = self.report_result() - prev + progress1 = self.count_virtualized - prev progress2 = len(self.inline_and_remove) - count_inline_and_remove - return progress1 or bool(progress2) + progress = progress1 or bool(progress2) + self.report_result(progress) + return progress def flush_failed_specializations(self): for key, (mode, specgraph) in self.specialized_graphs.items(): @@ -314,13 +332,14 @@ fobj = op.args[0].value._obj op = self.inline_and_remove[fobj.graph] log.mallocv('%s %s%s' % ('->'.join(chain), msg, exc)) + elif exc is None: + log.dot() def get_specialized_graph(self, graph, nodelist): assert len(graph.getargs()) == len(nodelist) if is_trivial_nodelist(nodelist): return 'trivial', graph - nodes = dict(zip(graph.getargs(), nodelist)) - virtualframe = VirtualFrame(graph, graph.startblock, 0, nodes) + virtualframe = VirtualFrame(graph, graph.startblock, 0, nodelist) key = virtualframe.getfrozenkey() try: return self.specialized_graphs[key] @@ -330,8 +349,7 @@ def build_specialized_graph(self, graph, key, nodelist): graph2 = copygraph(graph) - nodes = dict(zip(graph2.getargs(), nodelist)) - virtualframe = VirtualFrame(graph2, graph2.startblock, 0, nodes) + virtualframe = VirtualFrame(graph2, graph2.startblock, 0, nodelist) graphbuilder = GraphBuilder(self, graph2) specblock = graphbuilder.start_from_virtualframe(virtualframe) specblock.isstartblock = True @@ -373,10 +391,10 @@ def start_from_a_malloc(self, graph, block, v_result): assert v_result in [op.result for op in block.operations] - nodes = {} + nodelist = [] for v in block.inputargs: - nodes[v] = RuntimeSpecNode(v, v.concretetype) - trivialframe = VirtualFrame(graph, block, 0, nodes) + nodelist.append(RuntimeSpecNode(v, v.concretetype)) + trivialframe = VirtualFrame(graph, block, 0, nodelist) spec = BlockSpecializer(self, v_result) spec.initialize_renamings(trivialframe) self.pending_specializations.append(spec) @@ -957,8 +975,9 @@ except (KeyboardInterrupt, SystemExit): raise except Exception, e: - log.WARNING('constant-folding %s%r:' % (opname, args_v)) - log.WARNING(' %s: %s' % (e.__class__.__name__, e)) + pass + #log.WARNING('constant-folding %s%r:' % (opname, args_v)) + #log.WARNING(' %s: %s' % (e.__class__.__name__, e)) else: return (result,) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Mon Oct 13 13:41:25 2008 @@ -179,6 +179,18 @@ graph = self.check(f, [int], [19], 42, expected_calls=0) # inlined + def test_direct_call_unused_arg(self): + A = lltype.GcStruct('A', ('x', lltype.Signed)) + prebuilt_a = lltype.malloc(A) + def g(a, unused): + return a.x + def f(n): + a = lltype.malloc(A) + a.x = 15 + return g(a, n) + graph = self.check(f, [int], [42], 15, + expected_calls=1) # not inlined + def test_raises_simple(self): class MyExc(Exception): pass From arigo at codespeak.net Mon Oct 13 13:43:37 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 13 Oct 2008 13:43:37 +0200 (CEST) Subject: [pypy-svn] r59066 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081013114337.5919816A2FC@codespeak.net> Author: arigo Date: Mon Oct 13 13:43:36 2008 New Revision: 59066 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: - "for i in range" works. - recursion detection, trying to prevent non-termination. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Mon Oct 13 13:43:36 2008 @@ -120,8 +120,8 @@ class VirtualFrame(object): - def __init__(self, sourcegraph, sourceblock, nextopindex, - allnodes, callerframe=None): + def __init__(self, sourceblock, nextopindex, + allnodes, callerframe=None, calledgraphs={}): if isinstance(allnodes, dict): self.varlist = vars_alive_through_op(sourceblock, nextopindex) self.nodelist = [allnodes[v] for v in self.varlist] @@ -129,10 +129,10 @@ assert nextopindex == 0 self.varlist = sourceblock.inputargs self.nodelist = allnodes[:] - self.sourcegraph = sourcegraph self.sourceblock = sourceblock self.nextopindex = nextopindex self.callerframe = callerframe + self.calledgraphs = calledgraphs def get_nodes_in_use(self): return dict(zip(self.varlist, self.nodelist)) @@ -142,13 +142,13 @@ newframe.varlist = self.varlist newframe.nodelist = [node.copy(memo, flagreadonly) for node in self.nodelist] - newframe.sourcegraph = self.sourcegraph newframe.sourceblock = self.sourceblock newframe.nextopindex = self.nextopindex if self.callerframe is None: newframe.callerframe = None else: newframe.callerframe = self.callerframe.copy(memo, flagreadonly) + newframe.calledgraphs = self.calledgraphs return newframe def enum_call_stack(self): @@ -251,8 +251,7 @@ else: yield (block, op) elif op.opname == 'direct_call': - fobj = op.args[0].value._obj - graph = getattr(fobj, 'graph', None) + graph = graph_called_by(op) if graph in self.inline_and_remove: yield (block, op) @@ -339,7 +338,7 @@ assert len(graph.getargs()) == len(nodelist) if is_trivial_nodelist(nodelist): return 'trivial', graph - virtualframe = VirtualFrame(graph, graph.startblock, 0, nodelist) + virtualframe = VirtualFrame(graph.startblock, 0, nodelist) key = virtualframe.getfrozenkey() try: return self.specialized_graphs[key] @@ -349,7 +348,7 @@ def build_specialized_graph(self, graph, key, nodelist): graph2 = copygraph(graph) - virtualframe = VirtualFrame(graph2, graph2.startblock, 0, nodelist) + virtualframe = VirtualFrame(graph2.startblock, 0, nodelist) graphbuilder = GraphBuilder(self, graph2) specblock = graphbuilder.start_from_virtualframe(virtualframe) specblock.isstartblock = True @@ -394,7 +393,7 @@ nodelist = [] for v in block.inputargs: nodelist.append(RuntimeSpecNode(v, v.concretetype)) - trivialframe = VirtualFrame(graph, block, 0, nodelist) + trivialframe = VirtualFrame(block, 0, nodelist) spec = BlockSpecializer(self, v_result) spec.initialize_renamings(trivialframe) self.pending_specializations.append(spec) @@ -434,9 +433,9 @@ newframe = self.return_to_caller(currentframe, nodelist[0]) else: targetnodes = dict(zip(targetblock.inputargs, nodelist)) - newframe = VirtualFrame(currentframe.sourcegraph, - targetblock, 0, targetnodes, - callerframe=currentframe.callerframe) + newframe = VirtualFrame(targetblock, 0, targetnodes, + callerframe=currentframe.callerframe, + calledgraphs=currentframe.calledgraphs) rtnodes = newframe.find_rt_nodes() specblock = self.get_specialized_block(newframe, v_expand_malloc) @@ -650,6 +649,11 @@ newops_for_this_op = meth(op) newoperations += newops_for_this_op self.ops_produced_by_last_op = len(newops_for_this_op) + for op in newoperations: + if op.opname == 'direct_call': + graph = graph_called_by(op) + if graph in self.virtualframe.calledgraphs: + raise CannotVirtualize("recursion in residual call") self.specblock.operations = newoperations def follow_exits(self): @@ -847,10 +851,9 @@ return self.handle_default(op) def handle_op_direct_call(self, op): - fobj = op.args[0].value._obj - if not hasattr(fobj, 'graph'): + graph = graph_called_by(op) + if graph is None: return self.handle_default(op) - graph = fobj.graph nb_args = len(op.args) - 1 assert nb_args == len(graph.getargs()) newnodes = [self.getnode(v) for v in op.args[1:]] @@ -878,13 +881,12 @@ raise ValueError(kind) def get_updated_frame(self, op): - sourcegraph = self.virtualframe.sourcegraph sourceblock = self.virtualframe.sourceblock nextopindex = self.virtualframe.nextopindex self.nodes[op.result] = FutureReturnValue(op) - myframe = VirtualFrame(sourcegraph, sourceblock, nextopindex, - self.nodes, - self.virtualframe.callerframe) + myframe = VirtualFrame(sourceblock, nextopindex, self.nodes, + self.virtualframe.callerframe, + self.virtualframe.calledgraphs) del self.nodes[op.result] return myframe @@ -900,8 +902,12 @@ def handle_inlined_call(self, myframe, graph, newnodes): assert len(graph.getargs()) == len(newnodes) targetnodes = dict(zip(graph.getargs(), newnodes)) - calleeframe = VirtualFrame(graph, graph.startblock, 0, - targetnodes, myframe) + calledgraphs = myframe.calledgraphs.copy() + if graph in calledgraphs: + raise CannotVirtualize("recursion during inlining") + calledgraphs[graph] = True + calleeframe = VirtualFrame(graph.startblock, 0, + targetnodes, myframe, calledgraphs) self.virtualframe = calleeframe self.nodes = calleeframe.get_nodes_in_use() return [] @@ -985,3 +991,9 @@ rtnode = RuntimeSpecNode(None, v.concretetype) renamings[rtnode] = v return rtnode + +def graph_called_by(op): + assert op.opname == 'direct_call' + fobj = op.args[0].value._obj + graph = getattr(fobj, 'graph', None) + return graph Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Mon Oct 13 13:43:36 2008 @@ -425,6 +425,59 @@ return a.x * a.y self.check(fn9, [int], [6], 42, expected_calls=0) # inlined + def test_remove_for_in_range(self): + def fn10(n): + total = 0 + for i in range(n): + total += i + return total + self.check(fn10, [int], [10], 45) + + def test_recursion_spec(self): + class A: + pass + def make_chain(n): + a = A() + if n >= 0: + a.next = make_chain(n-1) + a.value = a.next.value + n + else: + a.value = 0 + return a + def fn11(n): + return make_chain(n).value + self.check(fn11, [int], [10], 55, + expected_calls=1) + + def test_recursion_inlining(self): + class A: + pass + def make_chain(a, n): + if n >= 0: + a.next = A() + make_chain(a.next, n-1) + a.value = a.next.value + n + else: + a.value = 0 + def fn12(n): + a = A() + make_chain(a, n) + return a.value + self.check(fn12, [int], [10], 55, + expected_mallocs=1, expected_calls=1) + + def test_constfold_exitswitch(self): + class A: + pass + def fn13(n): + a = A() + if lloperation.llop.same_as(lltype.Bool, True): + a.n = 4 + else: + a.n = -13 + return a.n + self.check(fn13, [int], [10], 4) + class TestLLTypeMallocRemoval(BaseMallocRemovalTest): type_system = 'lltype' From arigo at codespeak.net Mon Oct 13 13:44:37 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 13 Oct 2008 13:44:37 +0200 (CEST) Subject: [pypy-svn] r59067 - pypy/dist/pypy/translator/backendopt Message-ID: <20081013114437.E759A169FD4@codespeak.net> Author: arigo Date: Mon Oct 13 13:44:37 2008 New Revision: 59067 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py Log: Fix for test from previous checkin. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Mon Oct 13 13:44:37 2008 @@ -9,10 +9,14 @@ from pypy.rpython.lltypesystem.lloperation import llop -def virtualize_mallocs(translator, verbose=True): - mallocv = MallocVirtualizer(translator.graphs, translator.rtyper, verbose) +def virtualize_mallocs(translator, graphs, verbose=True): + newgraphs = graphs[:] + mallocv = MallocVirtualizer(newgraphs, translator.rtyper, verbose) while mallocv.remove_mallocs_once(): pass + assert newgraphs[:len(graphs)] == graphs + del newgraphs[:len(graphs)] + translator.graphs.extend(newgraphs) translator.checkgraphs() for graph in translator.graphs: join_blocks(graph) @@ -662,6 +666,19 @@ 'exitswitch') links = block.exits catch_exc = self.specblock.exitswitch == c_last_exception + + if not catch_exc and isinstance(self.specblock.exitswitch, Constant): + # constant-fold the switch + for exit in links: + if exit.exitcase == 'default': + break + if exit.llexitcase == self.specblock.exitswitch.value: + break + else: + raise Exception("exit case not found?") + links = (exit,) + self.specblock.exitswitch = None + if catch_exc and self.ops_produced_by_last_op == 0: # the last op of the sourceblock did not produce any # operation in specblock, so we need to discard the @@ -690,11 +707,12 @@ self.virtualframe, link.target, linkargsnodes, self.renamings, self.v_expand_malloc) # - newlink.exitcase = link.exitcase - if hasattr(link, 'llexitcase'): - newlink.llexitcase = link.llexitcase - if is_catch_link: - newlink.extravars(*extravars) + if self.specblock.exitswitch is not None: + newlink.exitcase = link.exitcase + if hasattr(link, 'llexitcase'): + newlink.llexitcase = link.llexitcase + if is_catch_link: + newlink.extravars(*extravars) newlinks.append(newlink) self.specblock.closeblock(*newlinks) From arigo at codespeak.net Mon Oct 13 13:45:05 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 13 Oct 2008 13:45:05 +0200 (CEST) Subject: [pypy-svn] r59068 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081013114505.97B1816A042@codespeak.net> Author: arigo Date: Mon Oct 13 13:45:05 2008 New Revision: 59068 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Test and fix. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Mon Oct 13 13:45:05 2008 @@ -399,7 +399,7 @@ nodelist.append(RuntimeSpecNode(v, v.concretetype)) trivialframe = VirtualFrame(block, 0, nodelist) spec = BlockSpecializer(self, v_result) - spec.initialize_renamings(trivialframe) + spec.initialize_renamings(trivialframe, keep_inputargs=True) self.pending_specializations.append(spec) self.pending_patch = (block, spec.specblock) @@ -600,16 +600,22 @@ self.v_expand_malloc = v_expand_malloc self.specblock = Block([]) - def initialize_renamings(self, virtualframe): + def initialize_renamings(self, virtualframe, keep_inputargs=False): # we make a copy of the original 'virtualframe' because the # specialize_operations() will mutate some of its content. virtualframe = virtualframe.copy({}) self.virtualframe = virtualframe self.nodes = virtualframe.get_nodes_in_use() self.renamings = {} # {RuntimeSpecNode(): Variable()} + if keep_inputargs: + assert virtualframe.varlist == virtualframe.sourceblock.inputargs specinputargs = [] - for rtnode in virtualframe.find_rt_nodes(): - v = rtnode.newvar() + for i, rtnode in enumerate(virtualframe.find_rt_nodes()): + if keep_inputargs: + v = virtualframe.varlist[i] + assert v.concretetype == rtnode.TYPE + else: + v = rtnode.newvar() self.renamings[rtnode] = v specinputargs.append(v) self.specblock.inputargs = specinputargs Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Mon Oct 13 13:45:05 2008 @@ -46,6 +46,7 @@ def check(self, fn, signature, args, expected_result, expected_mallocs=0, expected_calls=0): t = TranslationContext() + self.translator = t t.buildannotator().build_types(fn, signature) t.buildrtyper(type_system=self.type_system).specialize() graph = graphof(t, fn) @@ -478,6 +479,18 @@ return a.n self.check(fn13, [int], [10], 4) + def test_preserve_annotations_on_graph(self): + class A: + pass + def fn14(n): + a = A() + a.n = n + 1 + return a.n + graph = self.check(fn14, [int], [10], 11) + annotator = self.translator.annotator + assert annotator.binding(graph.getargs()[0]).knowntype is int + assert annotator.binding(graph.getreturnvar()).knowntype is int + class TestLLTypeMallocRemoval(BaseMallocRemovalTest): type_system = 'lltype' From arigo at codespeak.net Mon Oct 13 14:57:50 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 13 Oct 2008 14:57:50 +0200 (CEST) Subject: [pypy-svn] r59069 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081013125750.E2FAA16A337@codespeak.net> Author: arigo Date: Mon Oct 13 14:57:49 2008 New Revision: 59069 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Test and fix and some slight renamings in the code. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Mon Oct 13 14:57:49 2008 @@ -9,7 +9,7 @@ from pypy.rpython.lltypesystem.lloperation import llop -def virtualize_mallocs(translator, graphs, verbose=True): +def virtualize_mallocs(translator, graphs, verbose=False): newgraphs = graphs[:] mallocv = MallocVirtualizer(newgraphs, translator.rtyper, verbose) while mallocv.remove_mallocs_once(): @@ -141,20 +141,25 @@ def get_nodes_in_use(self): return dict(zip(self.varlist, self.nodelist)) - def copy(self, memo, flagreadonly={}): + def shallowcopy(self): newframe = VirtualFrame.__new__(VirtualFrame) newframe.varlist = self.varlist - newframe.nodelist = [node.copy(memo, flagreadonly) - for node in self.nodelist] + newframe.nodelist = self.nodelist newframe.sourceblock = self.sourceblock newframe.nextopindex = self.nextopindex - if self.callerframe is None: - newframe.callerframe = None - else: - newframe.callerframe = self.callerframe.copy(memo, flagreadonly) + newframe.callerframe = self.callerframe newframe.calledgraphs = self.calledgraphs return newframe + def copy(self, memo, flagreadonly={}): + newframe = self.shallowcopy() + newframe.nodelist = [node.copy(memo, flagreadonly) + for node in newframe.nodelist] + if newframe.callerframe is not None: + newframe.callerframe = newframe.callerframe.copy(memo, + flagreadonly) + return newframe + def enum_call_stack(self): frame = self while frame is not None: @@ -450,9 +455,13 @@ callerframe = currentframe.callerframe if callerframe is None: raise ForcedInline("return block") - for i in range(len(callerframe.nodelist)): - if isinstance(callerframe.nodelist[i], FutureReturnValue): - callerframe.nodelist[i] = retnode + nodelist = callerframe.nodelist + callerframe = callerframe.shallowcopy() + callerframe.nodelist = [] + for node in nodelist: + if isinstance(node, FutureReturnValue): + node = retnode + callerframe.nodelist.append(node) return callerframe def handle_catch(self, catchingframe, nodelist, renamings): @@ -675,14 +684,14 @@ if not catch_exc and isinstance(self.specblock.exitswitch, Constant): # constant-fold the switch - for exit in links: - if exit.exitcase == 'default': + for link in links: + if link.exitcase == 'default': break - if exit.llexitcase == self.specblock.exitswitch.value: + if link.llexitcase == self.specblock.exitswitch.value: break else: raise Exception("exit case not found?") - links = (exit,) + links = (link,) self.specblock.exitswitch = None if catch_exc and self.ops_produced_by_last_op == 0: Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Mon Oct 13 14:57:49 2008 @@ -479,6 +479,30 @@ return a.n self.check(fn13, [int], [10], 4) + def test_constfold_indirect_call(self): + skip("write me") + + def test_bug_on_links_to_return(self): + class A: + pass + def h1(n): + return n - 1 + def h2(n): + return n - 2 + def g(a): + a.n += 1 + if a.n > 5: + return h1 + else: + return h2 + def fn15(n): + a = A() + a.n = n + m = g(a)(n) + return a.n * m + assert fn15(10) == 99 + self.check(fn15, [int], [10], 99) + def test_preserve_annotations_on_graph(self): class A: pass From arigo at codespeak.net Mon Oct 13 15:12:11 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 13 Oct 2008 15:12:11 +0200 (CEST) Subject: [pypy-svn] r59070 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081013131211.5902B16A1B4@codespeak.net> Author: arigo Date: Mon Oct 13 15:12:10 2008 New Revision: 59070 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Test and fix. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Mon Oct 13 15:12:10 2008 @@ -945,6 +945,15 @@ self.nodes = calleeframe.get_nodes_in_use() return [] + def handle_op_indirect_call(self, op): + v_func = self.rename_nonvirtual(op.args[0], op) + if isinstance(v_func, Constant): + op = SpaceOperation('direct_call', [v_func] + op.args[1:-1], + op.result) + return self.handle_op_direct_call(op) + else: + return self.handle_default(op) + class FutureReturnValue(object): def __init__(self, op): Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Mon Oct 13 15:12:10 2008 @@ -10,6 +10,7 @@ from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.lltypesystem import lltype, llmemory, lloperation from pypy.rpython.ootypesystem import ootype +from pypy.rpython.annlowlevel import llhelper from pypy.rlib import objectmodel from pypy.rlib.rarithmetic import ovfcheck from pypy.conftest import option @@ -480,7 +481,18 @@ self.check(fn13, [int], [10], 4) def test_constfold_indirect_call(self): - skip("write me") + F = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) + class A: + pass + def h1(n): + return n - 1 + def fn16(n): + a = A() + a.n = n + h = llhelper(F, h1) + h2 = lloperation.llop.same_as(F, h) + return h2(a.n) + self.check(fn16, [int], [10], 9, expected_calls=1) def test_bug_on_links_to_return(self): class A: From fijal at codespeak.net Mon Oct 13 15:14:32 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 13 Oct 2008 15:14:32 +0200 (CEST) Subject: [pypy-svn] r59071 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test test/include Message-ID: <20081013131432.B625F16A2F7@codespeak.net> Author: fijal Date: Mon Oct 13 15:14:32 2008 New Revision: 59071 Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/include/ pypy/branch/cbuild-refactor/pypy/translator/platform/test/include/test.h Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py Log: Add a test for file copying. Cannot run, because I broke my scratchbox :( Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Mon Oct 13 15:14:32 2008 @@ -1,12 +1,45 @@ import py from pypy.translator.platform.linux import Linux, _run_subprocess from pypy.translator.platform import ExecutionResult, log +from pypy.tool.udir import udir def check_scratchbox(): if not py.path.local('/scratchbox/login').check(): py.test.skip("No scratchbox detected") class Maemo(Linux): + available_includedirs = ['/usr/include', '/tmp'] + + def _invent_new_name(self, basepath, base): + pth = basepath.join(base) + num = 0 + while pth.check(): + pth = basepath.join('%s_%d' % (base,num)) + num += 1 + return pth.ensure(dir=1) + + def _copy_files_to_new_dir(self, dir_from, pattern='*.h'): + new_dirpath = self._invent_new_name(udir, 'copied_includes') + files = py.path.local(dir_from).listdir(pattern) + for f in files: + f.copy(new_dirpath) + return new_dirpath + + def _includedirs(self, include_dirs): + """ Tweak includedirs so they'll be available through scratchbox + """ + res_incl_dirs = [] + for incl_dir in include_dirs: + incl_dir = py.path.local(incl_dir) + for available in self.available_includedirs: + if incl_dir.relto(available): + res_incl_dirs.append(str(incl_dir)) + break + else: + # we need to copy files to a place where it's accessible + res_incl_dirs.append(self._copy_files_to_new_dir(incl_dir)) + return ['-I%s' % (incl_dir,) for incl_dir in res_incl_dirs] + def _execute_c_compiler(self, cc, args, outname): log.execute('/scratchbox/login ' + cc + ' ' + ' '.join(args)) args = [cc] + args Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/include/test.h ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/include/test.h Mon Oct 13 15:14:32 2008 @@ -0,0 +1 @@ +#define XXX_STUFF 42 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py Mon Oct 13 15:14:32 2008 @@ -2,8 +2,11 @@ """ File containing maemo platform tests """ +import py +from pypy.tool.udir import udir from pypy.translator.platform.maemo import Maemo, check_scratchbox from pypy.translator.platform.test.test_platform import TestPlatform as BasicTest +from pypy.translator.tool.cbuild import ExternalCompilationInfo class TestMaemo(BasicTest): platform = Maemo() @@ -11,3 +14,20 @@ def setup_class(cls): check_scratchbox() + + def test_includes_outside_scratchbox(self): + cfile = udir.join('test_includes_outside_scratchbox.c') + cfile.write(''' + #include + #include "test.h" + int main() + { + printf("%d\\n", XXX_STUFF); + return 0; + } + ''') + includedir = py.magic.autopath().dirpath().join('include') + eci = ExternalCompilationInfo(include_dirs=(includedir,)) + executable = self.platform.compile([cfile], eci) + res = self.platform.execute(executable) + self.check_res(res) From arigo at codespeak.net Mon Oct 13 15:41:06 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 13 Oct 2008 15:41:06 +0200 (CEST) Subject: [pypy-svn] r59072 - pypy/dist/pypy/translator/backendopt Message-ID: <20081013134106.90C31169F66@codespeak.net> Author: arigo Date: Mon Oct 13 15:41:04 2008 New Revision: 59072 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py Log: Avoid a pass over all of translator.graphs. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Mon Oct 13 15:41:04 2008 @@ -1,5 +1,6 @@ from pypy.objspace.flow.model import Variable, Constant, Block, Link from pypy.objspace.flow.model import SpaceOperation, FunctionGraph, copygraph +from pypy.objspace.flow.model import checkgraph from pypy.objspace.flow.model import c_last_exception from pypy.translator.backendopt.support import log from pypy.translator.simplify import join_blocks @@ -14,12 +15,12 @@ mallocv = MallocVirtualizer(newgraphs, translator.rtyper, verbose) while mallocv.remove_mallocs_once(): pass + for graph in newgraphs: + checkgraph(graph) + join_blocks(graph) assert newgraphs[:len(graphs)] == graphs del newgraphs[:len(graphs)] translator.graphs.extend(newgraphs) - translator.checkgraphs() - for graph in translator.graphs: - join_blocks(graph) # ____________________________________________________________ From witulski at codespeak.net Mon Oct 13 18:06:27 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Mon, 13 Oct 2008 18:06:27 +0200 (CEST) Subject: [pypy-svn] r59073 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081013160627.7114216A386@codespeak.net> Author: witulski Date: Mon Oct 13 18:06:25 2008 New Revision: 59073 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: some registerallocation cleanup new Method move_to_register and new parameter for alloc_register, dontalloc Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py Mon Oct 13 18:06:25 2008 @@ -27,6 +27,7 @@ assert isinstance(location, Location) def to_string(self): + #return self.location.to_string() if isinstance(self.location, Stack64): return "_STACK" if isinstance(self.location, Register8): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Mon Oct 13 18:06:25 2008 @@ -27,15 +27,17 @@ if isinstance(gv_y,Immediate64): gv_w = self.allocate_register() self.mc.MOV(gv_w, gv_y) + [gv_z, gv_w] = self.move_to_registers([gv_z, gv_w]) method(gv_z, gv_w) else: + [gv_z, gv_y] = self.move_to_registers([gv_z, gv_y]) method(gv_z, gv_y) - return gv_z return op_int def make_one_argument_method(name): def op_int(self, gv_x): + [gv_x] = self.move_to_registers([gv_x]) method = getattr(self.mc, name) method(gv_x) return gv_x @@ -51,6 +53,9 @@ arg = lltype.Void return LL_TO_GENVAR[arg] +class WrongArgException(Exception): + pass + class Label(GenLabel): def __init__(self, startaddr, arg_positions, stackdepth): self.startaddr = startaddr @@ -102,17 +107,14 @@ @specialize.arg(1) def genop1(self, opname, gv_arg): - if isinstance(gv_arg, model.GenVar) and isinstance(gv_arg.location, Stack64): - gv_arg = self.move_back_to_register(gv_arg) + [gv_arg] = self.move_to_registers([gv_arg]) genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg) - + + # TODO: check at the right point: always after the last allocton! @specialize.arg(1) def genop2(self, opname, gv_arg1, gv_arg2): - if isinstance(gv_arg1, model.GenVar) and isinstance(gv_arg1.location, Stack64): - gv_arg1 = self.move_back_to_register(gv_arg1) - if isinstance(gv_arg2, model.GenVar) and isinstance(gv_arg2.location, Stack64): - gv_arg2 = self.move_back_to_register(gv_arg2) + [gv_arg1, gv_arg2] = self.move_to_registers([gv_arg1, gv_arg2]) genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg1, gv_arg2) @@ -155,11 +157,26 @@ self.mc.SHR(gv_x) return gv_x + def move_to_registers(self, registers, dont_alloc = None, move_imm_too = False): + if dont_alloc is None: + dont_alloc = [] + + for i in range(len(registers)): + if isinstance(registers[i], model.GenVar) and isinstance(registers[i].location, Stack64): + registers[i] = self.move_back_to_register(registers[i], dont_alloc) + # some operations dont suppoert immediateoperands + if move_imm_too and isinstance(registers[i], Immediate32): + gv_new = self.allocate_register(None, dont_alloc) + self.mc.MOV(gv_new, registers[i]) + registers[i] = gv_new + return registers + # IDIV RDX:RAX with QWREG - # supports only RAX (64bit) with QWREG + # supports only RAX (64bit) with QWREG def op_int_floordiv(self, gv_x, gv_y): gv_z = self.allocate_register("rax") - gv_w = self.allocate_register("rdx") + gv_w = self.allocate_register("rdx",["rax"]) + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], ["rax", "rdx"], move_imm_too=True) self.mc.MOV(gv_z, gv_x) self.mc.CDQ() #sign extention of rdx:rax if isinstance(gv_y, Immediate32): #support imm32 @@ -174,7 +191,7 @@ # FIXME: supports only RAX with QWREG def op_int_mod(self, gv_x, gv_y): gv_z = self.allocate_register("rax") - gv_w = self.allocate_register("rdx") + gv_w = self.allocate_register("rdx",["rax"]) self.mc.MOV(gv_z, gv_x) self.mc.XOR(gv_w, gv_w) self.mc.IDIV(gv_y) @@ -184,7 +201,12 @@ # return self.mc.NOT(gv_x) def op_int_gt(self, gv_x, gv_y): - self.mc.CMP(gv_x, gv_y) + if gv_x.to_string() == "_IMM32": + gv_w = self.allocate_register(None, ["rax"]) + self.mc.MOV(gv_w, gv_x) + self.mc.CMP(gv_w, gv_y) + else: + self.mc.CMP(gv_x, gv_y) # You can not use every register for # 8 bit operations, so you have to # choose rax,rcx or rdx @@ -194,38 +216,63 @@ return gv_z def op_int_lt(self, gv_x, gv_y): - self.mc.CMP(gv_x, gv_y) + if gv_x.to_string() == "_IMM32": + gv_w = self.allocate_register(None, ["rax"]) + self.mc.MOV(gv_w, gv_x) + self.mc.CMP(gv_w, gv_y) + else: + self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETL(IntVar(Register8("al"))) return gv_z def op_int_le(self, gv_x, gv_y): - self.mc.CMP(gv_x, gv_y) + if gv_x.to_string() == "_IMM32": + gv_w = self.allocate_register(None, ["rax"]) + self.mc.MOV(gv_w, gv_x) + self.mc.CMP(gv_w, gv_y) + else: + self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETLE(IntVar(Register8("al"))) return gv_z def op_int_eq(self, gv_x, gv_y): - self.mc.CMP(gv_x, gv_y) + if gv_x.to_string() == "_IMM32": + gv_w = self.allocate_register(None, ["rax"]) + self.mc.MOV(gv_w, gv_x) + self.mc.CMP(gv_w, gv_y) + else: + self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETE(IntVar(Register8("al"))) return gv_z def op_int_ne(self, gv_x, gv_y): - self.mc.CMP(gv_x, gv_y) + if gv_x.to_string() == "_IMM32": + gv_w = self.allocate_register(None, ["rax"]) + self.mc.MOV(gv_w, gv_x) + self.mc.CMP(gv_w, gv_y) + else: + self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETNE(IntVar(Register8("al"))) return gv_z def op_int_ge(self, gv_x, gv_y): - self.mc.CMP(gv_x, gv_y) + if gv_x.to_string() == "_IMM32": + gv_w = self.allocate_register(None, ["rax"]) + self.mc.MOV(gv_w, gv_x) + self.mc.CMP(gv_w, gv_y) + else: + self.mc.CMP(gv_x, gv_y) gv_z = self.allocate_register("rax") self.mc.SETGE(IntVar(Register8("al"))) return gv_z # the moves to pass arg. when making a jump to a block # the targetvars are only copys - #FIXME: problem with mapping of stackpositions + # FIXME: problem with mapping of stackpositions def _compute_moves(self, outputargs_gv, targetargs_gv): tar2src = {} tar2loc = {} @@ -288,29 +335,50 @@ self.mc.JMP(target.startaddr) self._close() - # FIXME: returns only ints - # FIXME: Double values in known_gv?? + # FIXME: returns only IntVars # TODO: support the allocation of 8bit Reg - def allocate_register(self, register=None): - if register is None: - if not self.freeregisters: - new_gv = self.spill_register() - self.known_gv.append(new_gv) - return new_gv + def allocate_register(self, register=None, dontalloc = None): + if dontalloc is None: + dontalloc = [] - new_gv = IntVar(Register64(self.freeregisters.popitem()[0])) + if register is None: + # dont use registers from dontalloc + # e.g you dont want to use rax because it is + # needed/used already somewhere else + leave = False + reg = None + seen_reg = 0 + while not leave: + # no or only "dontalloc" regs. are left + if not self.freeregisters or seen_reg == len(self.freeregisters): + new_gv = self.spill_register(dontalloc) + self.known_gv.append(new_gv) + return new_gv + # After one ore more loops: + # This reg is in dontalloc + if not reg == None: + self.freeregisters.append(reg) + reg = self.freeregisters.popitem()[0] + # leave if the reg is not in dontalloc + if reg not in dontalloc: + leave = True + seen_reg = seen_reg +1 + + new_gv = IntVar(Register64(reg)) self.known_gv.append(new_gv) return new_gv else: if register not in self.freeregisters: - # the register must be in the list! + # the register must be in the list. + # beacuse if its not free it is + # used by a gen_var for i in range(len(self.known_gv)): if isinstance(self.known_gv[i].location, Register64) and register == self.known_gv[i].location.reg: # move the values from the requiered # register to an other one and # return the requested one. - gv_temp = self.allocate_register() + gv_temp = self.allocate_register(None, dontalloc) self.mc.MOV(gv_temp, self.known_gv[i]) new_gv = IntVar(Register64(register)) self.known_gv.append(new_gv) @@ -320,7 +388,8 @@ # raised when the register is not in freereg. and not # used by a gen_var - raise Exception("error while register moves") + raise Exception("error while register moves") + del self.freeregisters[register] new_gv = IntVar(Register64(register)) self.known_gv.append(new_gv) @@ -353,16 +422,21 @@ # TODO: alloc strategy # TODO: support 8bit reg. alloc # just greddy spilling - def spill_register(self): + def spill_register(self, dont_spill=None): + if dont_spill is None: + dont_spill = [] # take the first gv which is not # on the stack gv_to_spill = None for i in range(len(self.known_gv)): - if not isinstance(self.known_gv[i].location, Stack64): - gv_to_spill = self.known_gv[i] - break + if isinstance(self.known_gv[i].location, Register64): + if self.known_gv[i].location.reg not in dont_spill: + gv_to_spill = self.known_gv[i] + break # there must be genVars which are # inside an register so: + if gv_to_spill == None: + raise WrongArgException("to many dont_spill/dont_alloc registers") assert isinstance(gv_to_spill.location, Register64) self.stackdepth = self.stackdepth +1 self.mc.PUSH(gv_to_spill) @@ -371,17 +445,17 @@ return new_gv # FIXME: pushed values are not allways poped (if not TOS) - def move_back_to_register(self, a_spilled_gv): + def move_back_to_register(self, a_spilled_gv, dont_alloc): # if a_spilled_gv is the top of stack if a_spilled_gv.location.offset == self.stackdepth: - gv_new = self.allocate_register() + gv_new = self.allocate_register(None, dont_alloc) self.mc.POP(gv_new) self.stackdepth = self.stackdepth -1 assert self.stackdepth >= 0 #update all offsets for i in range(len(self.known_gv)): if isinstance(self.known_gv[i].location, Stack64): - known_gv[i].location.offset = known_gv[i].location.offset -1 + self.known_gv[i].location.offset = self.known_gv[i].location.offset -1 a_spilled_gv = gv_new # TODO: free gv_new (no double values in known_gv) # TODO: look if there is a genVar with stackdepth @@ -391,7 +465,7 @@ else: # else access the memory # FIXME: if this genVar becomes the top of stack it will never be pushed - gv_new = self.allocate_register() + gv_new = self.allocate_register(None, dont_alloc) self.mc.MOV(gv_new, IntVar(Stack64(8*(self.stackdepth-a_spilled_gv.location.offset)))) a_spilled_gv = gv_new return a_spilled_gv Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Mon Oct 13 18:06:25 2008 @@ -514,8 +514,7 @@ test_calling_pause_direct = skip test_longwinded_and_direct = skip test_condition_result_cross_link_direct = skip - ##test_multiple_cmps = skip## - test_flipped_cmp_with_immediate = skip + #test_flipped_cmp_with_immediate = skip test_jump_to_block_with_many_vars = skip test_same_as = skip test_pause_and_resume_direct = skip From xoraxax at codespeak.net Mon Oct 13 23:32:51 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 13 Oct 2008 23:32:51 +0200 (CEST) Subject: [pypy-svn] r59075 - in pypy/dist/pypy/translator: goal tool tool/test Message-ID: <20081013213251.B6C6516A381@codespeak.net> Author: xoraxax Date: Mon Oct 13 23:32:49 2008 New Revision: 59075 Modified: pypy/dist/pypy/translator/goal/targettestdicts.py pypy/dist/pypy/translator/goal/targettestlistvsdict.py pypy/dist/pypy/translator/tool/staticsizereport.py pypy/dist/pypy/translator/tool/test/test_staticsizereport.py Log: Modify test targets to provide info that is more easy to compare, fix a bug in the staticsizereport code that resulted in incorrect accounting of inlined structures. Modified: pypy/dist/pypy/translator/goal/targettestdicts.py ============================================================================== --- pypy/dist/pypy/translator/goal/targettestdicts.py (original) +++ pypy/dist/pypy/translator/goal/targettestdicts.py Mon Oct 13 23:32:49 2008 @@ -14,7 +14,7 @@ # __________ Entry point __________ -test_dict = dict(map(lambda x: (x, hex(x)), range(5000))) +test_dict = dict(map(lambda x: (x, hex(x)), range(256, 4096))) reverse_dict = dict(map(lambda (x,y): (y,x), test_dict.items())) def entry_point(argv): Modified: pypy/dist/pypy/translator/goal/targettestlistvsdict.py ============================================================================== --- pypy/dist/pypy/translator/goal/targettestlistvsdict.py (original) +++ pypy/dist/pypy/translator/goal/targettestlistvsdict.py Mon Oct 13 23:32:49 2008 @@ -14,8 +14,9 @@ # __________ Entry point __________ -test_list = map(hex, range(5000)) -test_dict = dict(map(lambda x: (x, hex(x)), range(5000))) +numbers = range(1000, 5000) +test_list = map(str, numbers) +test_dict = dict(map(lambda x: (x, str(x)), numbers)) def entry_point(argv): if argv[1] == 'd': Modified: pypy/dist/pypy/translator/tool/staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/staticsizereport.py Mon Oct 13 23:32:49 2008 @@ -51,10 +51,14 @@ def values_to_nodes(database, values): nodes = [] for value in values: - if isinstance(typeOf(value), Ptr) and isinstance(typeOf(value._obj), ContainerType): - node = database.getcontainernode(value._obj) - if node.nodekind != 'func': - nodes.append(node) + if isinstance(typeOf(value), Ptr): + container = value._obj + if isinstance(typeOf(container), ContainerType): + node = database.getcontainernode(container) + if node.nodekind != 'func': + nodes.append(node) + elif isinstance(typeOf(value), ContainerType): # inlined container + nodes.extend(values_to_nodes(database, database.getcontainernode(value).enum_dependencies())) return nodes Modified: pypy/dist/pypy/translator/tool/test/test_staticsizereport.py ============================================================================== --- pypy/dist/pypy/translator/tool/test/test_staticsizereport.py (original) +++ pypy/dist/pypy/translator/tool/test/test_staticsizereport.py Mon Oct 13 23:32:49 2008 @@ -1,5 +1,6 @@ from pypy.translator.c.test.test_typed import CompilationTestCase from pypy.translator.tool.staticsizereport import group_static_size, guess_size +from pypy.rpython.lltypesystem import llmemory, lltype, rffi class TestStaticSizeReport(CompilationTestCase): def test_simple(self): @@ -23,6 +24,11 @@ def test_large_dict(self): d = {} + d_small = {1:2} + fixlist = [x for x in range(100)] + dynlist = [x for x in range(100)] + test_dict = dict(map(lambda x: (x, hex(x)), range(256, 4096))) + reverse_dict = dict(map(lambda (x,y): (y,x), test_dict.items())) class wrap: pass for x in xrange(100): @@ -30,9 +36,30 @@ i.x = x d[x] = i def f(x): - return d[x].x + 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]) - gcontainers = self.builder.db.globalcontainers() - dictvalnode = [node for node in gcontainers if "struct dicttable" in repr(node.obj)][0] + db = self.builder.db + gcontainers = list(db.globalcontainers()) + t = db.translator + rtyper = t.rtyper + get_container = lambda x: rtyper.getrepr(t.annotator.bookkeeper.immutablevalue(x)).convert_const(x)._obj + dictvalnode = db.getcontainernode(get_container(d)) + dictvalnode2 = db.getcontainernode(get_container(d_small)) + fixarrayvalnode = db.getcontainernode(get_container(fixlist)) + dynarrayvalnode = db.getcontainernode(get_container(dynlist)) + test_dictnode = db.getcontainernode(get_container(test_dict)) + reverse_dictnode = db.getcontainernode(get_container(reverse_dict)) + + S = rffi.sizeof(lltype.Signed) + P = rffi.sizeof(rffi.VOIDP) + B = 1 # bool assert guess_size(self.builder.db, dictvalnode, set()) > 100 - #size, num = group_static_size(self.builder.db, gcontainers) + assert guess_size(self.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) + From fijal at codespeak.net Tue Oct 14 06:34:35 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 14 Oct 2008 06:34:35 +0200 (CEST) Subject: [pypy-svn] r59079 - pypy/dist/pypy/doc Message-ID: <20081014043435.4D0C316A36B@codespeak.net> Author: fijal Date: Tue Oct 14 06:34:32 2008 New Revision: 59079 Modified: pypy/dist/pypy/doc/maemo.txt Log: Add an XXX from personal experience. Fix filename Modified: pypy/dist/pypy/doc/maemo.txt ============================================================================== --- pypy/dist/pypy/doc/maemo.txt (original) +++ pypy/dist/pypy/doc/maemo.txt Tue Oct 14 06:34:32 2008 @@ -172,7 +172,11 @@ http://yankandpaste.blogspot.com/2008/08/maemo-diablo-sdk-install-on-ubuntu-804.html -1. On ubuntu linux edit sysctl.conf to contain:: +1. On ubuntu linux edit /etc/sysctl.conf to contain:: + + XXX [fijal] on my machine vdso_enbled = 0 freezed machine and made in + unbootable without editing file first. It seems not to be needed + though. vm.vdso_enabled = 0 vm.mmap_min_addr = 4096 From fijal at codespeak.net Tue Oct 14 07:34:42 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 14 Oct 2008 07:34:42 +0200 (CEST) Subject: [pypy-svn] r59080 - in pypy/branch/cbuild-refactor/pypy: config translator/c/test translator/goal translator/platform Message-ID: <20081014053442.158B416A35E@codespeak.net> Author: fijal Date: Tue Oct 14 07:34:40 2008 New Revision: 59080 Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py pypy/branch/cbuild-refactor/pypy/translator/goal/translate.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Log: * Fix get_platform to use config, move platform to main config. * Add test_standalone for maemo * Start hacking to provide nice support for copying files Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/config/translationoption.py (original) +++ pypy/branch/cbuild-refactor/pypy/config/translationoption.py Tue Oct 14 07:34:40 2008 @@ -11,6 +11,10 @@ DEFL_CLEVER_MALLOC_REMOVAL_INLINE_THRESHOLD = 32.4 DEFL_LOW_INLINE_THRESHOLD = DEFL_INLINE_THRESHOLD / 2.0 +PLATFORMS = [ + 'maemo', +] + translation_optiondescription = OptionDescription( "translation", "Translation Options", [ BoolOption("stackless", "enable stackless features during compilation", @@ -251,6 +255,10 @@ cmdline="--cli-trace-calls"), BoolOption("exception_transformer", "Use exception transformer", default=False), ]), + ChoiceOption("platform", + "target platform", ['host'] + PLATFORMS, default='host', + cmdline='--platform'), + ]) def get_combined_translation_config(other_optdescr=None, @@ -347,16 +355,18 @@ # ---------------------------------------------------------------- -PLATFORMS = [ - 'host', - 'maemo', -] - -def set_platform(translateconfig, config): +def set_platform(config): from pypy.translator.platform import set_platform - set_platform(translateconfig.platform, config.translation.cc) + set_platform(config.translation.platform, config.translation.cc) def get_platform(config): # XXX use config - from pypy.translator.platform import platform - return platform + opt = config.translation.platform + if opt == 'maemo': + from pypy.translator.platform.maemo import Maemo + return Maemo(config.translation.cc) + elif opt == 'host': + from pypy.translator.platform import host + return host + else: + raise ValueError(opt) Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Tue Oct 14 07:34:40 2008 @@ -10,221 +10,242 @@ from pypy.tool.autopath import pypydir -def test_hello_world(): - def entry_point(argv): - os.write(1, "hello world\n") - argv = argv[1:] - os.write(1, "argument count: " + str(len(argv)) + "\n") - for s in argv: - os.write(1, " '" + str(s) + "'\n") - return 0 - - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('hi there') - assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') - -def test_print(): - def entry_point(argv): - print "hello simpler world" - argv = argv[1:] - print "argument count:", len(argv) - print "arguments:", argv - print "argument lengths:", - print [len(s) for s in argv] - return 0 +class TestStandalone(object): + config = None + + def test_hello_world(self): + def entry_point(argv): + os.write(1, "hello world\n") + argv = argv[1:] + os.write(1, "argument count: " + str(len(argv)) + "\n") + for s in argv: + os.write(1, " '" + str(s) + "'\n") + return 0 + + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('hi there') + assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') + + def test_print(self): + def entry_point(argv): + print "hello simpler world" + argv = argv[1:] + print "argument count:", len(argv) + print "arguments:", argv + print "argument lengths:", + print [len(s) for s in argv] + return 0 + + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('hi there') - assert data.startswith('''hello simpler world\n''' - '''argument count: 2\n''' - '''arguments: [hi, there]\n''' - '''argument lengths: [2, 5]\n''') - # NB. RPython has only str, not repr, so str() on a list of strings - # gives the strings unquoted in the list - -def test_counters(): - from pypy.rpython.lltypesystem import lltype - from pypy.rpython.lltypesystem.lloperation import llop - def entry_point(argv): - llop.instrument_count(lltype.Void, 'test', 2) - llop.instrument_count(lltype.Void, 'test', 1) - llop.instrument_count(lltype.Void, 'test', 1) - llop.instrument_count(lltype.Void, 'test', 2) - llop.instrument_count(lltype.Void, 'test', 1) - return 0 - t = TranslationContext() - t.config.translation.instrument = True - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('hi there') + assert data.startswith('''hello simpler world\n''' + '''argument count: 2\n''' + '''arguments: [hi, there]\n''' + '''argument lengths: [2, 5]\n''') + # NB. RPython has only str, not repr, so str() on a list of strings + # gives the strings unquoted in the list + + def test_counters(self): + from pypy.rpython.lltypesystem import lltype + from pypy.rpython.lltypesystem.lloperation import llop + def entry_point(argv): + llop.instrument_count(lltype.Void, 'test', 2) + llop.instrument_count(lltype.Void, 'test', 1) + llop.instrument_count(lltype.Void, 'test', 1) + llop.instrument_count(lltype.Void, 'test', 2) + llop.instrument_count(lltype.Void, 'test', 1) + return 0 + t = TranslationContext(self.config) + t.config.translation.instrument = True + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() - cbuilder = CStandaloneBuilder(t, entry_point, config=t.config) # xxx - cbuilder.generate_source() - cbuilder.compile() + cbuilder = CStandaloneBuilder(t, entry_point, config=t.config) # xxx + cbuilder.generate_source() + cbuilder.compile() - counters_fname = udir.join("_counters_") - os.putenv('_INSTRUMENT_COUNTERS', str(counters_fname)) - try: - data = cbuilder.cmdexec() - finally: - os.unsetenv('_INSTRUMENT_COUNTERS') + counters_fname = udir.join("_counters_") + os.putenv('_INSTRUMENT_COUNTERS', str(counters_fname)) + try: + data = cbuilder.cmdexec() + finally: + os.unsetenv('_INSTRUMENT_COUNTERS') + + f = counters_fname.open('rb') + counters_data = f.read() + f.close() + + import struct + counters = struct.unpack("LLL", counters_data) + + assert counters == (0,3,2) + + def test_prof_inline(self): + if sys.platform == 'win32': + py.test.skip("instrumentation support is unix only for now") + def add(a,b): + return a + b - b + b - b + b - b + b - b + b - b + b - b + b + def entry_point(argv): + tot = 0 + x = int(argv[1]) + while x > 0: + tot = add(tot, x) + x -= 1 + os.write(1, str(tot)) + return 0 + from pypy.translator.interactive import Translation + t = Translation(entry_point, backend='c', standalone=True) + # 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) + # counters + t.backendopt(inline_threshold=all.INLINE_THRESHOLD_FOR_TEST*0.5, + profile_based_inline="500") + exe = t.compile() + out = py.process.cmdexec("%s 500" % exe) + assert int(out) == 500*501/2 + + def test_frexp(self): + import math + def entry_point(argv): + m, e = math.frexp(0) + x, y = math.frexp(0) + print m, x + return 0 + + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() - f = counters_fname.open('rb') - counters_data = f.read() - f.close() - - import struct - counters = struct.unpack("LLL", counters_data) - - assert counters == (0,3,2) - -def test_prof_inline(): - if sys.platform == 'win32': - py.test.skip("instrumentation support is unix only for now") - def add(a,b): - return a + b - b + b - b + b - b + b - b + b - b + b - b + b - def entry_point(argv): - tot = 0 - x = int(argv[1]) - while x > 0: - tot = add(tot, x) - x -= 1 - os.write(1, str(tot)) - return 0 - from pypy.translator.interactive import Translation - t = Translation(entry_point, backend='c', standalone=True) - # 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) - # counters - t.backendopt(inline_threshold=all.INLINE_THRESHOLD_FOR_TEST*0.5, - profile_based_inline="500") - exe = t.compile() - out = py.process.cmdexec("%s 500" % exe) - assert int(out) == 500*501/2 - -def test_frexp(): - import math - def entry_point(argv): - m, e = math.frexp(0) - x, y = math.frexp(0) - print m, x - return 0 + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('hi there') + assert map(float, data.split()) == [0.0, 0.0] + + def test_profopt(self): + def add(a,b): + return a + b - b + b - b + b - b + b - b + b - b + b - b + b + def entry_point(argv): + tot = 0 + x = int(argv[1]) + while x > 0: + tot = add(tot, x) + x -= 1 + os.write(1, str(tot)) + 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="") + # 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="", + noprofopt=True) + # no counters + t.backendopt() + exe = t.compile() + out = py.process.cmdexec("%s 500" % exe) + assert int(out) == 500*501/2 + + def test_standalone_large_files(self): + from pypy.module.posix.test.test_posix2 import need_sparse_files + need_sparse_files() + filename = str(udir.join('test_standalone_largefile')) + r4800000000 = r_longlong(4800000000L) + def entry_point(argv): + fd = os.open(filename, os.O_RDWR | os.O_CREAT, 0644) + os.lseek(fd, r4800000000, 0) + os.write(fd, "$") + newpos = os.lseek(fd, 0, 1) + if newpos == r4800000000 + 1: + print "OK" + else: + print "BAD POS" + os.close(fd) + return 0 + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('hi there') + assert data.strip() == "OK" + + def test_separate_files(self): + # One file in translator/c/src + fname = py.path.local(pypydir).join( + 'translator', 'c', 'src', 'll_strtod.h') + + # One file in (another) subdir of the temp directory + dirname = udir.join("test_dir").ensure(dir=1) + fname2 = dirname.join("test_genc.c") + fname2.write(""" + void f() { + LL_strtod_formatd("%5f", 12.3); + }""") + + files = [fname, fname2] + + def entry_point(argv): + return 0 + + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.eci = cbuilder.eci.merge( + ExternalCompilationInfo(separate_module_files=files)) + cbuilder.generate_source() - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('hi there') - assert map(float, data.split()) == [0.0, 0.0] - -def test_profopt(): - def add(a,b): - return a + b - b + b - b + b - b + b - b + b - b + b - b + b - def entry_point(argv): - tot = 0 - x = int(argv[1]) - while x > 0: - tot = add(tot, x) - x -= 1 - os.write(1, str(tot)) - 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="") - # 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="", - noprofopt=True) - # no counters - t.backendopt() - exe = t.compile() - out = py.process.cmdexec("%s 500" % exe) - assert int(out) == 500*501/2 - -def test_standalone_large_files(): - from pypy.module.posix.test.test_posix2 import need_sparse_files - need_sparse_files() - filename = str(udir.join('test_standalone_largefile')) - r4800000000 = r_longlong(4800000000L) - def entry_point(argv): - fd = os.open(filename, os.O_RDWR | os.O_CREAT, 0644) - os.lseek(fd, r4800000000, 0) - os.write(fd, "$") - newpos = os.lseek(fd, 0, 1) - if newpos == r4800000000 + 1: - print "OK" - else: - print "BAD POS" - os.close(fd) - return 0 - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('hi there') - assert data.strip() == "OK" - -def test_separate_files(): - # One file in translator/c/src - fname = py.path.local(pypydir).join( - 'translator', 'c', 'src', 'll_strtod.h') - - # One file in (another) subdir of the temp directory - dirname = udir.join("test_dir").ensure(dir=1) - fname2 = dirname.join("test_genc.c") - fname2.write(""" - void f() { - LL_strtod_formatd("%5f", 12.3); - }""") + makefile = udir.join(cbuilder.modulename, 'Makefile').read() - files = [fname, fname2] + # generated files are compiled in the same directory + assert " ../test_dir/test_genc.c" in makefile + assert " ../test_dir/test_genc.o" in makefile + + # 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.o" in makefile + +class TestMaemo(TestStandalone): + def setup_class(cls): + from pypy.translator.platform.maemo import check_scratchbox + check_scratchbox() + from pypy.config.pypyoption import get_pypy_config + config = get_pypy_config(translating=True) + config.translation.platform = 'maemo' + cls.config = config - def entry_point(argv): - return 0 + def test_separate_files(self): + py.test.skip("Unsupported") - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() + def test_profopt(self): + py.test.skip("Unsupported") - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.eci = cbuilder.eci.merge( - ExternalCompilationInfo(separate_module_files=files)) - cbuilder.generate_source() - - makefile = udir.join(cbuilder.modulename, 'Makefile').read() - - # generated files are compiled in the same directory - assert " ../test_dir/test_genc.c" in makefile - assert " ../test_dir/test_genc.o" in makefile - - # 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.o" in makefile + def test_prof_inline(self): + py.test.skip("Unsupported") def test_cross_compilation(): py.test.skip("Skip for now") Modified: pypy/branch/cbuild-refactor/pypy/translator/goal/translate.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/goal/translate.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/goal/translate.py Tue Oct 14 07:34:40 2008 @@ -52,9 +52,6 @@ ChoiceOption("opt", "optimization level", OPT_LEVELS, default=DEFAULT_OPT_LEVEL, cmdline="--opt -O"), - ChoiceOption("platform", - "target platform", ['host'] + PLATFORMS, default='host', - cmdline='--platform'), BoolOption("profile", "cProfile (to debug the speed of the translation process)", default=False, @@ -163,7 +160,7 @@ translating=True) # apply the platform settings - set_platform(translateconfig, config) + set_platform(config) # apply the optimization level settings set_opt_level(config, translateconfig.opt) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Tue Oct 14 07:34:40 2008 @@ -127,8 +127,9 @@ return ['-I%s' % (idir,) for idir in include_dirs] def _compile_args_from_eci(self, eci): - include_dirs = self._includedirs(eci.include_dirs) - return (self.cflags + list(eci.compile_extra) + include_dirs) + include_dirs = self._preprocess_dirs(eci.include_dirs) + args = self._includedirs(include_dirs) + return (self.cflags + list(eci.compile_extra) + args) def _link_args_from_eci(self, eci): library_dirs = self._libdirs(eci.library_dirs) @@ -136,6 +137,10 @@ return (library_dirs + libraries + self.link_flags + list(eci.link_extra)) + def _preprocess_dirs(self, include_dirs): + # hook for maemo + return include_dirs + def _args_for_shared(self, args): return ['-shared'] + args @@ -217,7 +222,8 @@ rel_ofiles = [rel_cfile[:-2]+'.o' for rel_cfile in rel_cfiles] m.cfiles = rel_cfiles - rel_includedirs = [pypyrel(incldir) for incldir in eci.include_dirs] + rel_includedirs = [pypyrel(incldir) for incldir in + self._preprocess_dirs(eci.include_dirs)] m.comment('automatically generated makefile') definitions = [ Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Tue Oct 14 07:34:40 2008 @@ -25,7 +25,7 @@ f.copy(new_dirpath) return new_dirpath - def _includedirs(self, include_dirs): + def _preprocess_dirs(self, include_dirs): """ Tweak includedirs so they'll be available through scratchbox """ res_incl_dirs = [] @@ -38,7 +38,7 @@ else: # we need to copy files to a place where it's accessible res_incl_dirs.append(self._copy_files_to_new_dir(incl_dir)) - return ['-I%s' % (incl_dir,) for incl_dir in res_incl_dirs] + return res_incl_dirs def _execute_c_compiler(self, cc, args, outname): log.execute('/scratchbox/login ' + cc + ' ' + ' '.join(args)) From fijal at codespeak.net Tue Oct 14 08:31:19 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 14 Oct 2008 08:31:19 +0200 (CEST) Subject: [pypy-svn] r59081 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081014063119.3446316A2D1@codespeak.net> Author: fijal Date: Tue Oct 14 08:31:16 2008 New Revision: 59081 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Log: * Add a cache * Add a pypy-specific hack, not to mess too much Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Tue Oct 14 08:31:16 2008 @@ -9,6 +9,7 @@ class Maemo(Linux): available_includedirs = ['/usr/include', '/tmp'] + copied_cache = {} def _invent_new_name(self, basepath, base): pth = basepath.join(base) @@ -19,11 +20,22 @@ return pth.ensure(dir=1) def _copy_files_to_new_dir(self, dir_from, pattern='*.h'): - new_dirpath = self._invent_new_name(udir, 'copied_includes') - files = py.path.local(dir_from).listdir(pattern) - for f in files: - f.copy(new_dirpath) - return new_dirpath + try: + return self.copied_cache[dir_from] + except KeyError: + new_dirpath = self._invent_new_name(udir, 'copied_includes') + files = py.path.local(dir_from).listdir(pattern) + for f in files: + f.copy(new_dirpath) + # XXX + srcdir = py.path.local(dir_from).join('src') + if srcdir.check(dir=1): + target = new_dirpath.join('src').ensure(dir=1) + for f in srcdir.listdir(pattern): + f.copy(target) + # XXX + self.copied_cache[dir_from] = new_dirpath + return new_dirpath def _preprocess_dirs(self, include_dirs): """ Tweak includedirs so they'll be available through scratchbox From arigo at codespeak.net Tue Oct 14 11:54:56 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 14 Oct 2008 11:54:56 +0200 (CEST) Subject: [pypy-svn] r59082 - pypy/trunk/pypy/rpython/test Message-ID: <20081014095456.A1AD916A4E5@codespeak.net> Author: arigo Date: Tue Oct 14 11:54:55 2008 New Revision: 59082 Modified: pypy/trunk/pypy/rpython/test/test_rstr.py Log: Fix these tests to work even in the presence of constant-folding in the flow space. Modified: pypy/trunk/pypy/rpython/test/test_rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rstr.py (original) +++ pypy/trunk/pypy/rpython/test/test_rstr.py Tue Oct 14 11:54:55 2008 @@ -396,22 +396,25 @@ def test_str_slice(self): const = self.const - def fn(): - s = const('hello') + def fn(n): + s = [const('hello'), const('world')][n] # non-constant s1 = s[:3] s2 = s[3:] s3 = s[3:10] return s1+s2 == s and s2+s1 == const('lohel') and s1+s3 == s - res = self.interpret(fn, ()) + res = self.interpret(fn, [0]) assert res def test_str_slice_minusone(self): const = self.const - def fn(): + def fn(n): s = const('hello') z = const('h') + lst = [s, z] # uncontantify s and z + s = lst[n] + z = lst[n+1] return s[:-1]+z[:-1] - res = self.interpret(fn, ()) + res = self.interpret(fn, [0]) assert self.ll_to_string(res) == const('hell') def test_strformat(self): From arigo at codespeak.net Tue Oct 14 13:31:19 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 14 Oct 2008 13:31:19 +0200 (CEST) Subject: [pypy-svn] r59083 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081014113119.7E85E16A440@codespeak.net> Author: arigo Date: Tue Oct 14 13:31:17 2008 New Revision: 59083 Modified: pypy/trunk/pypy/objspace/std/sliceobject.py pypy/trunk/pypy/objspace/std/test/test_sliceobject.py Log: (antocuni, arigo) Precise test, and fix, for normalize_simple_slice(). This should fix failing llassert's in pypy-c :-/ Modified: pypy/trunk/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/sliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/sliceobject.py Tue Oct 14 13:31:17 2008 @@ -81,12 +81,17 @@ def normalize_simple_slice(space, length, w_start, w_stop): """Helper for the {get,set,del}slice multimethod implementations.""" + # this returns a pair (start, stop) which is usable for slicing + # a sequence of the given length in an RPython-friendly way, i.e. + # guaranteeing that: + # * 0 <= start <= length + # * start <= stop start = space.int_w(w_start) stop = space.int_w(w_stop) if start < 0: start = 0 - if stop > length: - stop = length + if start > length: + start = length if stop < start: stop = start return start, stop Modified: pypy/trunk/pypy/objspace/std/test/test_sliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_sliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_sliceobject.py Tue Oct 14 13:31:17 2008 @@ -1,3 +1,4 @@ +from pypy.objspace.std.sliceobject import normalize_simple_slice class TestW_SliceObject: @@ -20,6 +21,27 @@ w_slice = space.newslice(w_None, w_None, w(0)) self.space.raises_w(space.w_ValueError, w_slice.indices3, space, 10) + def test_normalize_simple_slice(self): + space = self.space + w = space.wrap + + def getslice(length, start, stop): + # returns range(length)[start:stop] but without special + # support for negative start or stop + return [i for i in range(length) if start <= i < stop] + + assert getslice(10, 2, 5) == [2, 3, 4] + + for length in range(5): + for start in range(-2*length-2, 2*length+3): + for stop in range(-2*length-2, 2*length+3): + mystart, mystop = normalize_simple_slice(space, length, + w(start), w(stop)) + assert 0 <= mystart <= length + assert mystart <= mystop + assert (getslice(length, start, stop) == + getslice(length, mystart, mystop)) + class AppTest_SliceObject: def test_new(self): From iko at codespeak.net Tue Oct 14 13:48:04 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Tue, 14 Oct 2008 13:48:04 +0200 (CEST) Subject: [pypy-svn] r59087 - pypy/dist/pypy/module/unicodedata Message-ID: <20081014114804.538D416A4B5@codespeak.net> Author: iko Date: Tue Oct 14 13:48:03 2008 New Revision: 59087 Added: pypy/dist/pypy/module/unicodedata/btreecompress.py Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Log: use btree for storing unicode data (WIP) using a class has too much overhead (20K nodes need 450K to store, plus 100k for the string data and 150k for the codepoint->name tables). It should be possible to halve at least the node storage. Added: pypy/dist/pypy/module/unicodedata/btreecompress.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/unicodedata/btreecompress.py Tue Oct 14 13:48:03 2008 @@ -0,0 +1,166 @@ +MINLIST = 5 # minimum number of codepoints in range to make a list +MAXBLANK = 8 # max number of holes in a row in list range + +classdef = """ +class BTreeEntry(object): + substring = "" + codepoint = -1 + left = right = parent = None + + def __init__(self, substring, parent, left=False, codepoint=-1): + self.substring = substring + self.codepoint = codepoint + self.parent = parent + self.left = self.right = None + if parent: + if left: + assert parent.left is None + parent.left = self + else: + assert parent.right is None + parent.right = self + +def btree_lookup(name): + charnode = _charnode_0_ + while charnode: + if charnode.codepoint != -1 and name == charnode.substring: + return charnode.codepoint + if name.startswith(charnode.substring): + name = name[len(charnode.substring):] + charnode = charnode.left + else: + charnode = charnode.right + raise KeyError, name +""" + +def findranges(d): + ranges = [] + for i in range(max(d)+1): + if i in d: + if not ranges: + ranges.append((i,i)) + last = i + continue + if last + 1 == i: + ranges[-1] = (ranges[-1][0], i) + else: + ranges.append((i,i)) + last = i + return ranges + +def collapse_ranges(ranges): + collapsed = [ranges[0]] + for i in range(1,len(ranges)): + lows, lowe = collapsed[-1] + highs, highe = ranges[i] + if highs - lowe < MAXBLANK: + collapsed[-1] = (lows, highe) + else: + collapsed.append(ranges[i]) + + return collapsed + +def build_compression_tree(outfile, ucdata): + print >> outfile, classdef + + reversedict = {} + rootnode = gen_compression_tree( + outfile, ucdata.keys(), ucdata, reversedict) + + function = ["def lookup_charcode(code):", + " res = None"] + ranges = collapse_ranges(findranges(reversedict)) + for low, high in ranges: + if high - low <= MINLIST: + for code in range(low, high + 1): + if code in reversedict: + function.append( + " if code == %d: res = %s" % + (code, reversedict[code])) + continue + + function.append( + " if %d <= code <= %d: res = _charnames_%d[code-%d]" % ( + low, high, low, low)) + + print >> outfile, "_charnames_%d = [" % (low,) + for code in range(low, high + 1): + print >> outfile, "%s," % (reversedict.get(code),) + print >> outfile, "]\n" + + function.extend([" if res is None: raise KeyError, code", + " rstr = []", + " left = res.left", + " while res:", + " if res.left is left:", + " rstr.insert(0, res.substring)", + " left = res", + " res = res.parent", + " return ''.join(rstr)", + "", + ]) + print >> outfile, '\n'.join(function) + +def gen_compression_tree(outfile, stringlist, ucdata, reversedict, parent=None, parent_str="", left=False, counter=[0]): + # Find "best" startstring + if not stringlist: + return None + codes = {} + for string in stringlist: + for stop in range(1, len(string) + 1): + codes[string[:stop]] = codes.get(string[:stop], 0) + 1 + + s = [((freq), code) for (code, freq) in codes.iteritems()] + s.sort() + if not s: + return None + newcode = s[-1][1] + + has_substring = [] + other_substring = [] + codepoint = None + for string in stringlist: + if string == newcode: + codepoint = ucdata[parent_str+string] + elif string.startswith(newcode): + has_substring.append(string[len(newcode):]) + else: + other_substring.append(string) + + btnode = "_charnode_%d_" % (counter[0],) + args = '%r, %s' % (newcode, parent) + if left: + args += ', left=True' + if codepoint: + args += ', codepoint=%d' % (codepoint,) + reversedict[codepoint] = btnode + + print >> outfile, "%s = BTreeEntry(%s)" % (btnode, args) + counter[0] += 1 + + gen_compression_tree( + outfile, has_substring, ucdata, reversedict, + parent=btnode, parent_str=parent_str+newcode, + left=True, counter=counter) + gen_compression_tree( + outfile, other_substring, ucdata, reversedict, + parent=btnode, parent_str=parent_str, + left=False, counter=counter) + + return btnode + +def count_tree(tree): + def subsum(tree, cset): + if not tree: + return 0, 0 + cset.add(tree.substring) + lcount, ldepth = subsum(tree.left,cset) + rcount, rdepth = subsum(tree.right,cset) + return lcount+rcount+1, max(ldepth, rdepth) + 1 + + cset = set() + nodecount = subsum(tree, cset) + strsize = sum(3*4 + len(s) for s in cset) + nchars = sum(map(len, cset)) + + return strsize, nodecount, nchars Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/generate_unicodedb.py (original) +++ pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Tue Oct 14 13:48:03 2008 @@ -313,83 +313,12 @@ print >> outfile, 'def combining(code): return _get_record(code)[4]' def write_character_names(outfile, table): - def findranges(d): - ranges = [] - for i in range(max(d)+1): - if i in d: - if not ranges: - ranges.append((i,i)) - last = i - continue - if last + 1 == i: - ranges[-1] = (ranges[-1][0], i) - else: - ranges.append((i,i)) - last = i - return ranges - - def collapse_ranges(ranges): - collapsed = [ranges[0]] - for i in range(1,len(ranges)): - lows, lowe = collapsed[-1] - highs, highe = ranges[i] - if highs - lowe < 8: - collapsed[-1] = (lows, highe) - else: - collapsed.append(ranges[i]) - - return collapsed - - names = [table[code].name for code in range(len(table)) if table[code].name] - codelist = compression.build_compression_table(names) - print >> outfile, "_codelist =", - pprint.pprint(codelist, outfile) - - codes = set(code for code in range(len(table)) if table[code].name) - ranges = collapse_ranges(findranges(codes)) - - f_reverse_dict = ["def _gen_reverse_dict():", - " res = {}"] - function = ["def lookup_charcode(code):", - " from pypy.module.unicodedata import compression", - " res = None"] - for low, high in ranges: - if high - low <= 5: - # Too short for list - for code in range(low, high + 1): - name = table[code].name - if name: - function.append( - " if code == %d: res = %r" % ( - code, compression.compress(codelist, name))) - f_reverse_dict.append( - " res[%r] = %d" % ( - compression.compress(codelist, name), code)) - continue - function.append( - " if %d <= code <= %d: res = _charnames_%d[code-%d]" % ( - low, high, low, low)) - f_reverse_dict.extend([ - " for i in range(%d, %d):" % (low, high+1), - " name = _charnames_%d[i-%d]" % (low, low), - " if name is not None:", - " res[name] = i", - ]) - print >> outfile, "_charnames_%d = [" % (low,) - for code in range(low, high + 1): - name = table[code].name - if name: - print >> outfile, '%r,' % ( - compression.compress(codelist, name)) - else: - print >> outfile, 'None,' - print >> outfile, "]\n" - function.extend([" if res is None: raise KeyError, code", - " return compression.uncompress(_codelist, res)\n"]) - print >> outfile, '\n'.join(function) - f_reverse_dict.append(" return res\n") - print >> outfile, '\n'.join(f_reverse_dict) + import btreecompress + + names = dict((table[code].name,code) for code in range(len(table)) if table[code].name) + + btreecompress.build_compression_tree(outfile, names) def writeUnicodedata(version, table, outfile): # Version @@ -403,8 +332,6 @@ write_character_names(outfile, table) print >> outfile, ''' -_code_by_name = _gen_reverse_dict() - _cjk_prefix = "CJK UNIFIED IDEOGRAPH-" _hangul_prefix = 'HANGUL SYLLABLE ' @@ -463,12 +390,11 @@ raise KeyError def lookup(name): - from pypy.module.unicodedata import compression if name[:len(_cjk_prefix)] == _cjk_prefix: return _lookup_cjk(name[len(_cjk_prefix):]) if name[:len(_hangul_prefix)] == _hangul_prefix: return _lookup_hangul(name[len(_hangul_prefix):]) - return _code_by_name[compression.compress(_codelist, name)] + return btree_lookup(name) def name(code): if (0x3400 <= code <= 0x4DB5 or From arigo at codespeak.net Tue Oct 14 13:54:40 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 14 Oct 2008 13:54:40 +0200 (CEST) Subject: [pypy-svn] r59088 - pypy/trunk/pypy/objspace/std Message-ID: <20081014115440.C189916A01F@codespeak.net> Author: arigo Date: Tue Oct 14 13:54:40 2008 New Revision: 59088 Modified: pypy/trunk/pypy/objspace/std/sliceobject.py Log: (antocuni around, arigo) Tweak to let the annotator prove that start >= 0. Modified: pypy/trunk/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/sliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/sliceobject.py Tue Oct 14 13:54:40 2008 @@ -88,10 +88,10 @@ # * start <= stop start = space.int_w(w_start) stop = space.int_w(w_stop) - if start < 0: - start = 0 if start > length: start = length + if start < 0: + start = 0 if stop < start: stop = start return start, stop From antocuni at codespeak.net Tue Oct 14 14:21:32 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 14 Oct 2008 14:21:32 +0200 (CEST) Subject: [pypy-svn] r59092 - in pypy/trunk/pypy/translator: cli/src jvm/src/pypy oosupport/test_template Message-ID: <20081014122132.4F30316A47F@codespeak.net> Author: antocuni Date: Tue Oct 14 14:21:30 2008 New Revision: 59092 Modified: pypy/trunk/pypy/translator/cli/src/pypylib.cs pypy/trunk/pypy/translator/jvm/src/pypy/PyPy.java pypy/trunk/pypy/translator/oosupport/test_template/runtest.py Log: properly quote list and arrays of characters when used as return values in tests. This fixes getslice_not_constant_folded in both gencli and genjvm Modified: pypy/trunk/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/trunk/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/trunk/pypy/translator/cli/src/pypylib.cs Tue Oct 14 14:21:30 2008 @@ -49,6 +49,10 @@ object tmp = (object)item; res += ToPython((string)tmp) + ","; } + else if (item.GetType() == typeof(char)) { + object tmp = (object)item; + res += pypy.test.Result.ToPython((char)tmp) + ","; + } else res += ToPython(item) + ","; @@ -448,6 +452,10 @@ object tmp = (object)item; res += pypy.test.Result.ToPython((string)tmp) + ","; } + else if (item.GetType() == typeof(char)) { + object tmp = (object)item; + res += pypy.test.Result.ToPython((char)tmp) + ","; + } else res += pypy.test.Result.ToPython(item) + ","; } Modified: pypy/trunk/pypy/translator/jvm/src/pypy/PyPy.java ============================================================================== --- pypy/trunk/pypy/translator/jvm/src/pypy/PyPy.java (original) +++ pypy/trunk/pypy/translator/jvm/src/pypy/PyPy.java Tue Oct 14 14:21:30 2008 @@ -417,6 +417,8 @@ sb.append("]"); return sb.toString(); } + if (o instanceof Character) + return escaped_char(((Character)o).charValue()); if (o instanceof String) { return escaped_string((String)o); } Modified: pypy/trunk/pypy/translator/oosupport/test_template/runtest.py ============================================================================== --- pypy/trunk/pypy/translator/oosupport/test_template/runtest.py (original) +++ pypy/trunk/pypy/translator/oosupport/test_template/runtest.py Tue Oct 14 14:21:30 2008 @@ -73,3 +73,10 @@ return None assert self.interpret(fn, [False]) is None + def test_list_of_chars(self): + def fn(): + return ['a', 'b', 'c'] + res = self.interpret(fn, []) + res = self.ll_to_list(res) + assert res == ['a', 'b', 'c'] + From antocuni at codespeak.net Tue Oct 14 16:43:27 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 14 Oct 2008 16:43:27 +0200 (CEST) Subject: [pypy-svn] r59094 - in pypy/branch/oo-jit/pypy: jit/codegen/cli translator/cli Message-ID: <20081014144327.4539116A47C@codespeak.net> Author: antocuni Date: Tue Oct 14 16:43:26 2008 New Revision: 59094 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/translator/cli/dotnet.py Log: keep track of which BranchBuilder are still alive, and emit the code for the method as soon as every of those is closed Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Tue Oct 14 16:43:26 2008 @@ -492,6 +492,16 @@ def get_op_Return(self, gv_returnvar): raise NotImplementedError + def branch_closed(self): + # XXX: it's not needed to iterate over all branches + allclosed = True + for branchbuilder in self.branches: + if branchbuilder.is_open: + allclosed = False + break + if allclosed: + self.emit_code() + def emit_code(self): # emit initialization code self.emit_preamble() @@ -541,14 +551,6 @@ def get_op_Return(self, gv_returnvar): return ops.Return(self, gv_returnvar) - def emit_code(self): - MethodGenerator.emit_code(self) - self.emit_flexswitches() - - def emit_flexswitches(self): - for meth in self.graphinfo.flexswitch_meths: - meth.emit_code() - def emit_preamble(self): if not self.graphinfo.has_flexswitches: return @@ -646,16 +648,21 @@ self.rgenop = meth.rgenop self.il_label = il_label self.operations = [] - self.is_open = False + self.is_open = True self.genconsts = meth.genconsts def start_writing(self): self.is_open = True + def close(self): + assert self.is_open + self.is_open = False + self.meth.branch_closed() + def finish_and_return(self, sigtoken, gv_returnvar): op = self.meth.get_op_Return(gv_returnvar) self.appendop(op) - self.is_open = False + self.close() def finish_and_goto(self, outputargs_gv, label): inputargs_gv = label.inputargs_gv @@ -663,7 +670,8 @@ op = ops.FollowLink(self.meth, outputargs_gv, inputargs_gv, label.il_label) self.appendop(op) - self.is_open = False + self.close() + @specialize.arg(1) def genop1(self, opname, gv_arg): @@ -773,14 +781,14 @@ op = ops.DoFlexSwitch(self.meth, gv_flexswitch, gv_exitswitch, args_gv) self.appendop(op) - self.is_open = False + self.close() return flexswitch, default_branch def appendop(self, op): self.operations.append(op) def end(self): - self.meth.emit_code() + pass def replayops(self): assert not self.is_open Modified: pypy/branch/oo-jit/pypy/translator/cli/dotnet.py ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/dotnet.py (original) +++ pypy/branch/oo-jit/pypy/translator/cli/dotnet.py Tue Oct 14 16:43:26 2008 @@ -365,6 +365,8 @@ TYPE = x._FUNC assert isinstance(TYPE, ootype.StaticMethod) return typeof(TYPE) + elif x is ootype.nullruntimeclass: + return None else: name = x._INSTANCE._assembly_qualified_name t = CLR.System.Type.GetType(name) From pedronis at codespeak.net Tue Oct 14 17:01:16 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 14 Oct 2008 17:01:16 +0200 (CEST) Subject: [pypy-svn] r59095 - in pypy/build/bot2/pypybuildbot: . test Message-ID: <20081014150116.15B9116A482@codespeak.net> Author: pedronis Date: Tue Oct 14 17:01:15 2008 New Revision: 59095 Modified: pypy/build/bot2/pypybuildbot/summary.py pypy/build/bot2/pypybuildbot/test/test_summary.py Log: - fix the performance issue, trashing the lru is not such a great plan - added some statics code that insert comment in the pages - buildbot has the notions of both FAILURE and EXCEPTION Modified: pypy/build/bot2/pypybuildbot/summary.py ============================================================================== --- pypy/build/bot2/pypybuildbot/summary.py (original) +++ pypy/build/bot2/pypybuildbot/summary.py Tue Oct 14 17:01:15 2008 @@ -1,10 +1,10 @@ -import urllib +import urllib, time import py html = py.xml.html from buildbot.status.web.base import HtmlResource -from buildbot.status.builder import FAILURE +from buildbot.status.builder import FAILURE, EXCEPTION class RevisionOutcomeSet(object): @@ -71,12 +71,22 @@ def get_run_stdios(self): return {self.key: (self, self._run_stdio)} + class RevisionOutcomeSetCache(object): - CACHESIZE = 10 - def __init__(self): + def __init__(self, cachesize=10): self._outcome_sets = {} self._lru = [] + self._hits = 0 + self._misses = 0 + self.cachesize = cachesize + + def reset(self): + self._hits = 0 + self._misses = 0 + + def stats(self): + return "hits: %d, misses: %d" % (self._hits, self._misses) def _load_outcome_set(self, status, key): builderName, buildNumber = key @@ -93,7 +103,8 @@ pytest_log = logs['pytestLog'] stdio_log = logs['stdio'] break - elif stdio_log is None and step.getResults()[0] == FAILURE: + elif (stdio_log is None and + step.getResults()[0] in (FAILURE, EXCEPTION)): failure = ' '.join(step.getText()) stdio_log = logs.get('stdio') @@ -119,18 +130,19 @@ pass self._lru.append(key) try: - return self._outcome_sets[key] + outcome_set = self._outcome_sets[key] + self._hits += 1 + return outcome_set except KeyError: pass - if len(self._lru) > self.CACHESIZE: + self._misses += 1 + if len(self._lru) > self.cachesize: dead_key = self._lru.pop(0) self._outcome_sets.pop(dead_key, None) outcome_set = self._load_outcome_set(status, key) self._outcome_sets[key] = outcome_set return outcome_set -outcome_set_cache = RevisionOutcomeSetCache() - class GatherOutcomeSet(object): def __init__(self, map): @@ -190,7 +202,10 @@ # ________________________________________________________________ -N = 10 +N = 5 + +outcome_set_cache = RevisionOutcomeSetCache(10*(N+1)) + def colsizes(namekeys): colsizes = None @@ -300,6 +315,9 @@ section.append(html.br()) self.sections.append(section) + def add_comment(self, comm): + self.sections.append(py.xml.raw("" % comm)) + def render(self): body_html = html.div(self.sections) return body_html.unicode() @@ -328,6 +346,9 @@ return "%s %s" % (mod, testname) def body(self, request): + t0 = time.time() + outcome_set_cache.reset() + builder = request.args.get('builder', []) build = request.args.get('build', []) if not builder or not build: @@ -343,7 +364,9 @@ longrepr = outcome_set.get_longrepr(namekey) - return html.pre(longrepr).unicode() + return html.div([html.pre(longrepr), + py.xml.raw("" % outcome_set_cache.stats()) + ]).unicode() def getProp(obj, name, default=None): try: @@ -412,16 +435,22 @@ revBuilds = revs.setdefault(rev, {}) # pick the most recent or ? if builderName not in revBuilds: - key = (builderName, build.getNumber()) - outcome_set = outcome_set_cache.get(status, key) - revBuilds[builderName] = outcome_set + revBuilds[builderName] = build.getNumber() for branch, (revs, no_revision_builds) in branches.items(): self._prune_revs(revs, N) + for rev, revBuilds in revs.iteritems(): + for builderName, buildNumber in revBuilds.items(): + key = (builderName, buildNumber) + outcome_set = outcome_set_cache.get(status, key) + revBuilds[builderName] = outcome_set return branches def body(self, request): + t0 = time.time() + outcome_set_cache.reset() + status = self.getStatus(request) page = SummaryPage() @@ -445,4 +474,8 @@ page.add_section(outcome_sets) page.add_no_revision_builds(status, no_revision_builds) + t1 = time.time() + total_time = time.time()-t0 + page.add_comment('t=%.2f; %s' % (total_time, + outcome_set_cache.stats())) return page.render() Modified: pypy/build/bot2/pypybuildbot/test/test_summary.py ============================================================================== --- pypy/build/bot2/pypybuildbot/test/test_summary.py (original) +++ pypy/build/bot2/pypybuildbot/test/test_summary.py Tue Oct 14 17:01:15 2008 @@ -92,8 +92,7 @@ assert res == ' ' def test_RevisionOutcomeSetCache(self): - cache = summary.RevisionOutcomeSetCache() - cache.CACHESIZE = 3 + cache = summary.RevisionOutcomeSetCache(cachesize=3) calls = [] def load(x, y): calls.append(y) From pedronis at codespeak.net Tue Oct 14 17:04:44 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 14 Oct 2008 17:04:44 +0200 (CEST) Subject: [pypy-svn] r59096 - pypy/build/bot2 Message-ID: <20081014150444.76FB216A4E4@codespeak.net> Author: pedronis Date: Tue Oct 14 17:04:44 2008 New Revision: 59096 Modified: pypy/build/bot2/TODO Log: this should have been solved now Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Tue Oct 14 17:04:44 2008 @@ -12,8 +12,6 @@ - pypy-c py.test -A support -- look into why the full summary page but not single rev is slowish - - have a way for the involved tool to avoid color escapes even when there's a tty (because of buildbot pty usage) - move most buildbots to be over python 2.5 (?) From pedronis at codespeak.net Tue Oct 14 17:19:51 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 14 Oct 2008 17:19:51 +0200 (CEST) Subject: [pypy-svn] r59097 - pypy/build/bot2/pypybuildbot Message-ID: <20081014151951.2D27316A56C@codespeak.net> Author: pedronis Date: Tue Oct 14 17:19:49 2008 New Revision: 59097 Modified: pypy/build/bot2/pypybuildbot/summary.py Log: trying to sort ! failures first Modified: pypy/build/bot2/pypybuildbot/summary.py ============================================================================== --- pypy/build/bot2/pypybuildbot/summary.py (original) +++ pypy/build/bot2/pypybuildbot/summary.py Tue Oct 14 17:19:49 2008 @@ -279,12 +279,20 @@ lines.append([bars(), "\n"]) failed = set() - for rev, outcome_set in by_rev: - failed.update(outcome_set.failed) + exploded = set() + for rev, outcome_set in by_rev: + for failure in outcome_set.failed: + letter = outcome_set.get_outcome(failure) + if letter == '!': + exploded.add(failure) + failed.add(failure) colwidths = colsizes(failed) - for failure in sorted(failed): + def sorting(x): + return (x not in exploded, x) + + for failure in sorted(failed, key=sorting): line = [] for rev, outcome_set in by_rev: letter = outcome_set.get_outcome(failure) From pedronis at codespeak.net Tue Oct 14 17:22:28 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 14 Oct 2008 17:22:28 +0200 (CEST) Subject: [pypy-svn] r59098 - pypy/build/bot2 Message-ID: <20081014152228.2544216A581@codespeak.net> Author: pedronis Date: Tue Oct 14 17:22:27 2008 New Revision: 59098 Modified: pypy/build/bot2/TODO Log: this seems to be done too now Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Tue Oct 14 17:22:27 2008 @@ -1,8 +1,6 @@ - buildbot Nightly scheduler that can pick a uniform revision server side and with support for specifying possibly branches -- sort ! failures first - - improve summary page (defined in pypybuildbot/summary.page), support querying/slicing by builders, formatting and css From iko at codespeak.net Tue Oct 14 22:45:23 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Tue, 14 Oct 2008 22:45:23 +0200 (CEST) Subject: [pypy-svn] r59099 - in pypy/dist/pypy/module/unicodedata: . test Message-ID: <20081014204523.3834D16A657@codespeak.net> Author: iko Date: Tue Oct 14 22:45:20 2008 New Revision: 59099 Added: pypy/dist/pypy/module/unicodedata/test/test_trie.py pypy/dist/pypy/module/unicodedata/triegenerator.py (contents, props changed) - copied, changed from r59087, pypy/dist/pypy/module/unicodedata/btreecompress.py Removed: pypy/dist/pypy/module/unicodedata/btreecompress.py pypy/dist/pypy/module/unicodedata/compression.py pypy/dist/pypy/module/unicodedata/test/test_compression.py Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Log: Improve efficiency of storage of unicode data tree (which is rightly a trie as alexander pointed out) We now use 375k total for one unicode database (according to static data reporting, and it agrees with estimations based on sizes of strings and lists) Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/generate_unicodedb.py (original) +++ pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Tue Oct 14 22:45:20 2008 @@ -1,7 +1,6 @@ #!/usr/bin/env python import pprint -import compression MAXUNICODE = 0x10FFFF # the value of sys.maxunicode of wide Python builds @@ -314,11 +313,11 @@ def write_character_names(outfile, table): - import btreecompress + import triegenerator names = dict((table[code].name,code) for code in range(len(table)) if table[code].name) - btreecompress.build_compression_tree(outfile, names) + triegenerator.build_compression_tree(outfile, names) def writeUnicodedata(version, table, outfile): # Version @@ -394,7 +393,7 @@ return _lookup_cjk(name[len(_cjk_prefix):]) if name[:len(_hangul_prefix)] == _hangul_prefix: return _lookup_hangul(name[len(_hangul_prefix):]) - return btree_lookup(name) + return trie_lookup(name) def name(code): if (0x3400 <= code <= 0x4DB5 or Added: pypy/dist/pypy/module/unicodedata/test/test_trie.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/unicodedata/test/test_trie.py Tue Oct 14 22:45:20 2008 @@ -0,0 +1,22 @@ +import py +import StringIO + +from pypy.module.unicodedata import triegenerator + +def setup_module(mod): + mod.tmpdir = py.test.ensuretemp(mod.__name__) + mod.lines = lines = map(hex,map(hash, map(str, range(100)))) + # some extra handcrafted tests + lines.extend([ 'AAA', 'AAAA', 'AAAB', 'AAB', 'AABB' ]) + out = mod.tmpdir.join('btree.py') + o = out.open('w') + mod.trie = triegenerator.build_compression_tree( + o, dict(map(lambda (x,y):(y,x), enumerate(lines)))) + o.close() + mod.bt = out.pyimport() + + +def test_roundtrip(): + for i, line in enumerate(lines): + assert bt.lookup_charcode(i) == line + assert bt.trie_lookup(line) == i Copied: pypy/dist/pypy/module/unicodedata/triegenerator.py (from r59087, pypy/dist/pypy/module/unicodedata/btreecompress.py) ============================================================================== --- pypy/dist/pypy/module/unicodedata/btreecompress.py (original) +++ pypy/dist/pypy/module/unicodedata/triegenerator.py Tue Oct 14 22:45:20 2008 @@ -1,17 +1,44 @@ +import pprint + MINLIST = 5 # minimum number of codepoints in range to make a list MAXBLANK = 8 # max number of holes in a row in list range -classdef = """ -class BTreeEntry(object): - substring = "" - codepoint = -1 - left = right = parent = None +STRIDXBITS = 16 # bits to use for string index. Remaining are + # used for parent pointer + +# +# The trie of the unicode names is stored as a list, with 16-bit +# indexes for left, right and parent pointer, and also pointer +# into the string table (which is really just a long string) +# +# note, the size of the parent and the string pointer depend +# on STRIDXBITS, the latter being used for the string pointer +# and whatever is left for the parent pointer +# +# Each node is represented by 3 entrines in the _charnodes list: +# +# [leftright, parentstr, codepoint] +# +# (keeping them dirctly in the list rather than as 3-tuples +# saves 8 bytes per entry) +# +# where leftrigt is left << 16 | right +# and parentstr is parent << STRIDXBITS | string +# (with some additional logic to account for the fact that integers +# are signed) + +class TrieEntry(object): + allstrings = set() + counter = [0] def __init__(self, substring, parent, left=False, codepoint=-1): self.substring = substring + self.allstrings.add(substring) self.codepoint = codepoint self.parent = parent self.left = self.right = None + self.index = self.counter[0] + self.counter[0] += 1 if parent: if left: assert parent.left is None @@ -20,18 +47,95 @@ assert parent.right is None parent.right = self -def btree_lookup(name): - charnode = _charnode_0_ - while charnode: - if charnode.codepoint != -1 and name == charnode.substring: - return charnode.codepoint - if name.startswith(charnode.substring): - name = name[len(charnode.substring):] - charnode = charnode.left + def as_list(self, stringidx): + parentidx = leftidx = rightidx = -1 + if self.left: + leftidx = self.left.index + + if self.right: + rightidx = self.right.index + + if self.parent: + parentidx = self.parent.index + + stridx = stringidx[self.substring] + + leftright = (leftidx&0xffff) << 16 | (rightidx&0xffff) + if leftright >= 2**31: + leftright = int(~0x7fffffff | (0x7fffffff&leftright)) + + parentstr = ((parentidx & ((1<<(32-STRIDXBITS))-1)) << STRIDXBITS | + (stridx & ((1<= 2**31: + parentstr = int(~0x7fffffff | (0x7fffffff&parentstr)) + + return (leftright, parentstr, self.codepoint) + +classdef = """ +def trie_lookup(name): + charnode = 0 + while 0 <= charnode < 0xffff: # 16bit number, 0xffff = None + charnode *= 3 + leftright, parentstr, codepoint = _charnodes[charnode:charnode+3] + + if leftright < 0: + # XXX assumes msb is sign + left = 0x8000 | ((leftright & 0x7fffffff) >> 16) + else: + left = (leftright & 0x7fffffff) >> 16 + right = leftright & 0xffff + + if parentstr < 0: + # XXX assumes msb is sign + parent = 0x8000 | ((parentstr & 0x7fffffff) >> %(STRIDXBITS)d) + else: + parent = (parentstr & 0x7fffffff) >> %(STRIDXBITS)d + stridx = parentstr & ((1 << %(STRIDXBITS)d) - 1) + + strlen = ord(_stringtable[stridx]) + substring = _stringtable[stridx+1:stridx+1+strlen] + + if codepoint != -1 and name == substring: + return int(codepoint) + if name.startswith(substring): + name = name[strlen:] + charnode = left else: - charnode = charnode.right + charnode = right raise KeyError, name -""" + +def name_of_node(charnode): + res = [] + prevnode = -1 + while 0 <= charnode < 0xffff: # 16bit number, 0xffff = None + charnode *= 3 + leftright, parentstr, codepoint = _charnodes[charnode:charnode+3] + + if leftright < 0: + # XXX assumes msg is sign + left = 0x8000 | ((leftright & 0x7fffffff) >> 16) + else: + left = (leftright & 0x7fffffff) >> 16 + right = leftright & 0xffff + + if parentstr < 0: + # XXX assumes msb is sign + parent = 0x8000 | ((parentstr & 0x7fffffff) >> %(STRIDXBITS)d) + else: + parent = (parentstr & 0x7fffffff) >> %(STRIDXBITS)d + + if prevnode < 0 or prevnode == left: + stridx = parentstr & ((1<<%(STRIDXBITS)d)-1) + strlen = ord(_stringtable[stridx]) + substring = _stringtable[stridx+1:stridx+1+strlen] + res.insert(0, substring) + + prevnode = charnode // 3 + charnode = parent + + return ''.join(res) + +""" % globals() def findranges(d): ranges = [] @@ -64,11 +168,48 @@ print >> outfile, classdef reversedict = {} - rootnode = gen_compression_tree( - outfile, ucdata.keys(), ucdata, reversedict) + rootnode = gen_compression_tree(ucdata.keys(), ucdata, reversedict) + # write string table + print >> outfile, "_stringtable = (" + stringidx = {} + stridx = 0 + for string in rootnode.allstrings: + strlen = len(string) + assert strlen < 256, "Substring too long, > 255 chars" + print >> outfile, "%r" % (chr(strlen) + string) + stringidx[string] = stridx + stridx += strlen + 1 + + print >> outfile, ")" + + print >> outfile, "_dbg_stringidx = ", + pprint.pprint(stringidx,stream=outfile) + + assert stridx < (1< %d chars" % ( + ((1<> outfile, "_charnodes =", + pprint.pprint(newnodes, stream=outfile) + function = ["def lookup_charcode(code):", - " res = None"] + " res = -1"] ranges = collapse_ranges(findranges(reversedict)) for low, high in ranges: if high - low <= MINLIST: @@ -76,7 +217,7 @@ if code in reversedict: function.append( " if code == %d: res = %s" % - (code, reversedict[code])) + (code, reversedict[code].index)) continue function.append( @@ -85,23 +226,20 @@ print >> outfile, "_charnames_%d = [" % (low,) for code in range(low, high + 1): - print >> outfile, "%s," % (reversedict.get(code),) + if code in reversedict: + print >> outfile, "%s," % (reversedict[code].index,) + else: + print >> outfile, "-1," print >> outfile, "]\n" - function.extend([" if res is None: raise KeyError, code", - " rstr = []", - " left = res.left", - " while res:", - " if res.left is left:", - " rstr.insert(0, res.substring)", - " left = res", - " res = res.parent", - " return ''.join(rstr)", + function.extend([" if res == -1: raise KeyError, code", + " return name_of_node(res)", "", ]) print >> outfile, '\n'.join(function) + return rootnode -def gen_compression_tree(outfile, stringlist, ucdata, reversedict, parent=None, parent_str="", left=False, counter=[0]): +def gen_compression_tree(stringlist, ucdata, reversedict, parent=None, parent_str="", left=False): # Find "best" startstring if not stringlist: return None @@ -118,7 +256,7 @@ has_substring = [] other_substring = [] - codepoint = None + codepoint = -1 for string in stringlist: if string == newcode: codepoint = ucdata[parent_str+string] @@ -127,25 +265,18 @@ else: other_substring.append(string) - btnode = "_charnode_%d_" % (counter[0],) - args = '%r, %s' % (newcode, parent) - if left: - args += ', left=True' - if codepoint: - args += ', codepoint=%d' % (codepoint,) - reversedict[codepoint] = btnode - - print >> outfile, "%s = BTreeEntry(%s)" % (btnode, args) - counter[0] += 1 + btnode = TrieEntry(newcode, parent, left, codepoint) + if codepoint != -1: + reversedict[codepoint] = btnode gen_compression_tree( - outfile, has_substring, ucdata, reversedict, + has_substring, ucdata, reversedict, parent=btnode, parent_str=parent_str+newcode, - left=True, counter=counter) + left=True) gen_compression_tree( - outfile, other_substring, ucdata, reversedict, + other_substring, ucdata, reversedict, parent=btnode, parent_str=parent_str, - left=False, counter=counter) + left=False) return btnode @@ -164,3 +295,17 @@ nchars = sum(map(len, cset)) return strsize, nodecount, nchars + +if __name__ == '__main__': + testdata = { + 'AAA' : 0, + 'AAAA' : 1, + 'AAB' : 2, + 'ABA' : 3, + 'BBB' : 4, + 'ACA' : 5, + } + + import sys + + build_compression_tree(sys.stdout, testdata) From antocuni at codespeak.net Wed Oct 15 10:17:01 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 15 Oct 2008 10:17:01 +0200 (CEST) Subject: [pypy-svn] r59102 - pypy/trunk/pypy/translator/cli/test Message-ID: <20081015081701.B975416A1F8@codespeak.net> Author: antocuni Date: Wed Oct 15 10:17:00 2008 New Revision: 59102 Modified: pypy/trunk/pypy/translator/cli/test/test_carbonpython.py Log: skip this tests that fails inconsistently Modified: pypy/trunk/pypy/translator/cli/test/test_carbonpython.py ============================================================================== --- pypy/trunk/pypy/translator/cli/test/test_carbonpython.py (original) +++ pypy/trunk/pypy/translator/cli/test/test_carbonpython.py Wed Oct 15 10:17:00 2008 @@ -127,6 +127,7 @@ assert res == 42 def test_export_cliclass(self): + py.test.skip('it fails every other day on builbot, no clue why') from pypy.translator.cli.dotnet import CLR @export(CLR.System.Collections.ArrayList, int) From fijal at codespeak.net Wed Oct 15 15:37:06 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 15 Oct 2008 15:37:06 +0200 (CEST) Subject: [pypy-svn] r59103 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081015133706.A1C9C16A44B@codespeak.net> Author: fijal Date: Wed Oct 15 15:37:03 2008 New Revision: 59103 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Log: It seems we're insane enough to include .c files. Adapt Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Wed Oct 15 15:37:03 2008 @@ -19,7 +19,7 @@ num += 1 return pth.ensure(dir=1) - def _copy_files_to_new_dir(self, dir_from, pattern='*.h'): + def _copy_files_to_new_dir(self, dir_from, pattern='*.[ch]'): try: return self.copied_cache[dir_from] except KeyError: From antocuni at codespeak.net Wed Oct 15 16:05:27 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 15 Oct 2008 16:05:27 +0200 (CEST) Subject: [pypy-svn] r59104 - in pypy/branch/oo-jit/pypy/jit/codegen/cli: . test Message-ID: <20081015140527.7077016A466@codespeak.net> Author: antocuni Date: Wed Oct 15 16:05:26 2008 New Revision: 59104 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Log: be sure that genvars inside flexswitch cases are always mapped to their local variables, not to the vars of the containing method. Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py Wed Oct 15 16:05:26 2008 @@ -302,7 +302,7 @@ # setup the correct inputargs args_manager = graph.graphinfo.args_manager args_manager.copy_to_inputargs(graph, self.args_gv) - + # jumpto = flexswitch.execute(exitswitch, inputargs); # goto dispatch_jump; self.gv_flexswitch.load(graph) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Wed Oct 15 16:05:26 2008 @@ -125,10 +125,18 @@ def getkind(self): return type2class(self.getCliType()) - def load(self, builder): + def load(self, meth): + gv = meth.map_genvar(self) + gv._do_load(meth) + + def store(self, meth): + gv = meth.map_genvar(self) + gv._do_store(meth) + + def _do_load(self, meth): raise NotImplementedError - def store(self, builder): + def _do_store(self, meth): raise NotImplementedError class GenArgVar(GenVar): @@ -139,7 +147,7 @@ def getCliType(self): return self.cliType - def load(self, meth): + def _do_load(self, meth): if self.index == 0: meth.il.Emit(OpCodes.Ldarg_0) elif self.index == 1: @@ -151,23 +159,23 @@ else: meth.il.Emit(OpCodes.Ldarg, self.index) - def store(self, meth): + def _do_store(self, meth): meth.il.Emit(OpCodes.Starg, self.index) def __repr__(self): return "GenArgVar(%d)" % self.index class GenLocalVar(GenVar): - def __init__(self, v): + def __init__(self, meth, v): self.v = v def getCliType(self): return self.v.get_LocalType() - def load(self, meth): + def _do_load(self, meth): meth.il.Emit(OpCodes.Ldloc, self.v) - def store(self, meth): + def _do_store(self, meth): meth.il.Emit(OpCodes.Stloc, self.v) @@ -484,7 +492,7 @@ return result def newlocalvar(self, clitype): - return GenLocalVar(self.il.DeclareLocal(clitype)) + return GenLocalVar(self, self.il.DeclareLocal(clitype)) def map_genvar(self, gv_var): return gv_var @@ -683,10 +691,6 @@ @specialize.arg(1) def genop2(self, opname, gv_arg1, gv_arg2): - # XXX: also other ops - gv_arg1 = self.meth.map_genvar(gv_arg1) - gv_arg2 = self.meth.map_genvar(gv_arg2) - opcls = ops.getopclass2(opname) op = opcls(self.meth, gv_arg1, gv_arg2) self.appendop(op) @@ -777,6 +781,7 @@ gv_flexswitch = flexswitch.gv_flexswitch default_branch = self.meth.newbranch() label = default_branch.enter_next_block(args_gv) + flexswitch.llflexswitch.set_default_blockid(label.blockid) op = ops.DoFlexSwitch(self.meth, gv_flexswitch, gv_exitswitch, args_gv) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Wed Oct 15 16:05:26 2008 @@ -91,9 +91,6 @@ def test_known_nonzero(self): py.test.skip("something wrong with promotion") - def test_debug_assert_ptr_nonzero(self): - py.test.skip("something wrong with promotion") - def test_indirect_red_call_with_exc(self): py.test.skip("replay: NotImplementedError") From antocuni at codespeak.net Wed Oct 15 16:11:12 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 15 Oct 2008 16:11:12 +0200 (CEST) Subject: [pypy-svn] r59105 - pypy/branch/oo-jit/pypy/jit/codegen/cli/test Message-ID: <20081015141112.C790216A4BF@codespeak.net> Author: antocuni Date: Wed Oct 15 16:11:12 2008 New Revision: 59105 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Log: two more tests pass out of the box :-) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Wed Oct 15 16:11:12 2008 @@ -88,9 +88,6 @@ check_count_depth = False # see test_self_referential_structures - def test_known_nonzero(self): - py.test.skip("something wrong with promotion") - def test_indirect_red_call_with_exc(self): py.test.skip("replay: NotImplementedError") @@ -100,8 +97,5 @@ def test_learn_nonzeroness(self): py.test.skip("something wrong with promotion") - def test_freeze_booleffects_correctly(self): - py.test.skip("something wrong with promotion") - def test_degenerated_at_return(self): py.test.skip('test framework does not support getattr on returned instances') From witulski at codespeak.net Wed Oct 15 16:33:52 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Wed, 15 Oct 2008 16:33:52 +0200 (CEST) Subject: [pypy-svn] r59106 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081015143352.25E151684D6@codespeak.net> Author: witulski Date: Wed Oct 15 16:33:51 2008 New Revision: 59106 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: Added spilling features -Registers which contain GenConst are thrown away by spilling -compares use the throw away method -Added a new atribute in Register: throw away. The value inside is not needed anymore, so dont spill it FIXED some spilling bugs. -IMUL Exception: the result is in the other operand, it wont be thrown away -fixed the wrong calc of the stack in move_back_to_register -fixed bug in move_to_registers:append the alocatet registers to the dont_alloc list Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Wed Oct 15 16:33:51 2008 @@ -1,3 +1,4 @@ +from pypy.jit.codegen import model from pypy.jit.codegen.x86_64.objmodel import IntVar, Register8, Register64, Immediate8, Immediate32, Immediate64, Stack64 # Mapping from 64Bit-Register to coding (Rex.W or Rex.B , ModRM) @@ -270,6 +271,10 @@ # exchange the two arguments because # the result is in the first register if(op1.to_string()=="_QWREG" and op2.to_string()=="_QWREG"): + # after this operation, op2 contains + # the genVar/result, dont throw is away + op1.location.contains_genConst = False + op1.location.dont_spill(False) method(op2, op1) else: method(op1, op2) @@ -305,6 +310,7 @@ method = getattr(self, "_PUSH"+op1.to_string()) method(op1) + # TODO: support Register8 def MOV(self, op1, op2): method = getattr(self, "_MOV"+op1.to_string()+op2.to_string()) method(op1, op2) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py Wed Oct 15 16:33:51 2008 @@ -12,10 +12,26 @@ class Register64(Location): def __init__(self, reg): self.reg = reg + self.throw_away = False + self.contains_genConst = False + + def dont_spill(self, throw_away): + self.throw_away = throw_away # this value is not needed anymore + + def contains_Const(self): + self.contains_genConst = True class Register8(Location): def __init__(self, reg): self.reg = reg + self.throw_away = False + self.contains_genConst = False + + def dont_spill(self, throw_away): + self.throw_away = throw_away # this value is not needed anymore + + def contains_Const(self): + self.contains_genConst = True class Stack64(Location): def __init__(self, offset): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Wed Oct 15 16:33:51 2008 @@ -18,19 +18,24 @@ # to choose the right method in assembler.py def make_two_argument_method(name): def op_int(self, gv_x, gv_y): - gv_z = self.allocate_register() + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y]) + dont_alloc = [] + if not isinstance(gv_x, model.GenConst): + dont_alloc.append(gv_x.location.reg) + if not isinstance(gv_y, model.GenConst): + dont_alloc.append(gv_y.location.reg) + gv_z = self.allocate_register(None, dont_alloc) self.mc.MOV(gv_z, gv_x) method = getattr(self.mc, name) # Many operations don't support # 64 Bit Immmediates directly if isinstance(gv_y,Immediate64): - gv_w = self.allocate_register() + dont_alloc.append(gv_z.location.reg) + gv_w = self.allocate_register(None, dont_alloc) self.mc.MOV(gv_w, gv_y) - [gv_z, gv_w] = self.move_to_registers([gv_z, gv_w]) method(gv_z, gv_w) else: - [gv_z, gv_y] = self.move_to_registers([gv_z, gv_y]) method(gv_z, gv_y) return gv_z return op_int @@ -106,39 +111,38 @@ pass @specialize.arg(1) - def genop1(self, opname, gv_arg): - [gv_arg] = self.move_to_registers([gv_arg]) + def genop1(self, opname, gv_arg): genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg) - # TODO: check at the right point: always after the last allocton! @specialize.arg(1) - def genop2(self, opname, gv_arg1, gv_arg2): - [gv_arg1, gv_arg2] = self.move_to_registers([gv_arg1, gv_arg2]) + def genop2(self, opname, gv_arg1, gv_arg2): genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg1, gv_arg2) - op_int_add = make_two_argument_method("ADD") #TODO: use inc + op_int_add = make_two_argument_method("ADD") # TODO: use inc op_int_and = make_two_argument_method("AND") - op_int_dec = make_one_argument_method("DEC") #for debuging - op_int_inc = make_one_argument_method("INC") #for debuging + op_int_dec = make_one_argument_method("DEC") # for debuging + op_int_inc = make_one_argument_method("INC") # for debuging op_int_mul = make_two_argument_method("IMUL") op_int_neg = make_one_argument_method("NEG") - op_int_not = make_one_argument_method("NOT") #for debuging + op_int_not = make_one_argument_method("NOT") # for debuging op_int_or = make_two_argument_method("OR") - op_int_push = make_one_argument_method("PUSH") #for debuging - op_int_pop = make_one_argument_method("POP") #for debuging - op_int_sub = make_two_argument_method("SUB") # TODO: use DEC + op_int_push = make_one_argument_method("PUSH") # for debuging + op_int_pop = make_one_argument_method("POP") # for debuging + op_int_sub = make_two_argument_method("SUB") # TODO: use DEC op_int_xor = make_two_argument_method("XOR") # TODO: support reg8 def op_cast_bool_to_int(self, gv_x): + [gv_x] = self.move_to_registers([gv_x]) assert isinstance(gv_x, IntVar) and isinstance(gv_x.location,Register64) return gv_x # 0 xor 1 == 1 # 1 xor 1 == 0 def op_bool_not(self, gv_x): + [gv_x] = self.move_to_registers([gv_x]) self.mc.XOR(gv_x, Immediate32(1)) return gv_x @@ -146,6 +150,7 @@ # FIXME: uses rcx insted of cl def op_int_lshift(self, gv_x, gv_y): gv_z = self.allocate_register("rcx") + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], ["rcx"]) self.mc.MOV(gv_z, gv_y) self.mc.SHL(gv_x) return gv_x @@ -153,6 +158,7 @@ # FIXME: uses rcx insted of cl def op_int_rshift(self, gv_x, gv_y): gv_z = self.allocate_register("rcx") + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], ["rcx"]) self.mc.MOV(gv_z, gv_y) self.mc.SHR(gv_x) return gv_x @@ -164,34 +170,33 @@ for i in range(len(registers)): if isinstance(registers[i], model.GenVar) and isinstance(registers[i].location, Stack64): registers[i] = self.move_back_to_register(registers[i], dont_alloc) + dont_alloc.append(registers[i].location.reg) # some operations dont suppoert immediateoperands if move_imm_too and isinstance(registers[i], Immediate32): gv_new = self.allocate_register(None, dont_alloc) self.mc.MOV(gv_new, registers[i]) registers[i] = gv_new + dont_alloc.append(registers[i].location.reg) + registers[i].location.contains_Const() return registers # IDIV RDX:RAX with QWREG # supports only RAX (64bit) with QWREG def op_int_floordiv(self, gv_x, gv_y): gv_z = self.allocate_register("rax") - gv_w = self.allocate_register("rdx",["rax"]) + gv_w = self.allocate_register("rdx") [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], ["rax", "rdx"], move_imm_too=True) self.mc.MOV(gv_z, gv_x) self.mc.CDQ() #sign extention of rdx:rax - if isinstance(gv_y, Immediate32): #support imm32 - gv_u = self.allocate_register() - self.mc.MOV(gv_u,gv_y) - self.mc.IDIV(gv_u) - else: - self.mc.IDIV(gv_y) + self.mc.IDIV(gv_y) return gv_z # IDIV RDX:RAX with QWREG # FIXME: supports only RAX with QWREG def op_int_mod(self, gv_x, gv_y): gv_z = self.allocate_register("rax") - gv_w = self.allocate_register("rdx",["rax"]) + gv_w = self.allocate_register("rdx") + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], ["rax", "rdx"], move_imm_too=True) self.mc.MOV(gv_z, gv_x) self.mc.XOR(gv_w, gv_w) self.mc.IDIV(gv_y) @@ -200,72 +205,60 @@ # def op_int_invert(self, gv_x): # return self.mc.NOT(gv_x) + def throw_away_if_const(self, registers): + for i in range(len(registers)): + if registers[i].location.contains_genConst: + registers[i].location.dont_spill(True) + return registers + + # You can not use every register for + # 8 bit operations, so you have to + # choose rax,rcx or rdx + # TODO: use also rcx rdx def op_int_gt(self, gv_x, gv_y): - if gv_x.to_string() == "_IMM32": - gv_w = self.allocate_register(None, ["rax"]) - self.mc.MOV(gv_w, gv_x) - self.mc.CMP(gv_w, gv_y) - else: - self.mc.CMP(gv_x, gv_y) - # You can not use every register for - # 8 bit operations, so you have to - # choose rax,rcx or rdx - # TODO: use also rcx rdx + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], None, move_imm_too=True) + self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.throw_away_if_const([gv_x,gv_y]) gv_z = self.allocate_register("rax") self.mc.SETG(IntVar(Register8("al"))) return gv_z def op_int_lt(self, gv_x, gv_y): - if gv_x.to_string() == "_IMM32": - gv_w = self.allocate_register(None, ["rax"]) - self.mc.MOV(gv_w, gv_x) - self.mc.CMP(gv_w, gv_y) - else: - self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], None, move_imm_too=True) + self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.throw_away_if_const([gv_x,gv_y]) gv_z = self.allocate_register("rax") self.mc.SETL(IntVar(Register8("al"))) return gv_z def op_int_le(self, gv_x, gv_y): - if gv_x.to_string() == "_IMM32": - gv_w = self.allocate_register(None, ["rax"]) - self.mc.MOV(gv_w, gv_x) - self.mc.CMP(gv_w, gv_y) - else: - self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], None, move_imm_too=True) + self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.throw_away_if_const([gv_x,gv_y]) gv_z = self.allocate_register("rax") self.mc.SETLE(IntVar(Register8("al"))) return gv_z def op_int_eq(self, gv_x, gv_y): - if gv_x.to_string() == "_IMM32": - gv_w = self.allocate_register(None, ["rax"]) - self.mc.MOV(gv_w, gv_x) - self.mc.CMP(gv_w, gv_y) - else: - self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], None, move_imm_too=True) + self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.throw_away_if_const([gv_x,gv_y]) gv_z = self.allocate_register("rax") self.mc.SETE(IntVar(Register8("al"))) return gv_z def op_int_ne(self, gv_x, gv_y): - if gv_x.to_string() == "_IMM32": - gv_w = self.allocate_register(None, ["rax"]) - self.mc.MOV(gv_w, gv_x) - self.mc.CMP(gv_w, gv_y) - else: - self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], None, move_imm_too=True) + self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.throw_away_if_const([gv_x,gv_y]) gv_z = self.allocate_register("rax") self.mc.SETNE(IntVar(Register8("al"))) return gv_z def op_int_ge(self, gv_x, gv_y): - if gv_x.to_string() == "_IMM32": - gv_w = self.allocate_register(None, ["rax"]) - self.mc.MOV(gv_w, gv_x) - self.mc.CMP(gv_w, gv_y) - else: - self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.move_to_registers([gv_x, gv_y], None, move_imm_too=True) + self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.throw_away_if_const([gv_x,gv_y]) gv_z = self.allocate_register("rax") self.mc.SETGE(IntVar(Register8("al"))) return gv_z @@ -305,6 +298,7 @@ jump_if_false = _new_jump("jump_if_false", 1) jump_if_true = _new_jump('jump_if_true', 0) + # TODO: move stackpointer def finish_and_return(self, sigtoken, gv_returnvar): #self.mc.write("\xB8\x0F\x00\x00\x00") self._open() @@ -314,13 +308,14 @@ while not self.stackdepth == 0: self.mc.POP(gv_return) self.stackdepth = self.stackdepth -1 - if not gv_returnvar == None:#check void return + if not gv_returnvar == None:#check void return self.mc.MOV(gv_return, gv_returnvar) self.mc.RET() self._close() assert self.stackdepth == 0 - #FIXME: uses 32bit displ + # FIXME: uses 32bit displ + # TODO: return also stackdepth or pop! # if the label is greater than 32bit # it must be in a register (not supported) def finish_and_goto(self, outputargs_gv, target): @@ -337,6 +332,7 @@ # FIXME: returns only IntVars # TODO: support the allocation of 8bit Reg + # TODO: (Optimization)Don't remember genVars which contain konstants def allocate_register(self, register=None, dontalloc = None): if dontalloc is None: dontalloc = [] @@ -349,7 +345,7 @@ reg = None seen_reg = 0 while not leave: - # no or only "dontalloc" regs. are left + # none or only "dontalloc" regs. are left if not self.freeregisters or seen_reg == len(self.freeregisters): new_gv = self.spill_register(dontalloc) self.known_gv.append(new_gv) @@ -400,8 +396,8 @@ # TODO: args_gv muste be a list of unique GenVars # Spilling could change the location of a - # genVar after this Label. That will result in - # wrong a mapping in _compute_moves when leaving this block. + # genVar after this Label. That will result in a + # wrong mapping in _compute_moves when leaving this block. # So the parameters must be inmutable(copy them) def enter_next_block(self, args_gv): # move constants into an register @@ -437,27 +433,28 @@ # inside an register so: if gv_to_spill == None: raise WrongArgException("to many dont_spill/dont_alloc registers") - assert isinstance(gv_to_spill.location, Register64) - self.stackdepth = self.stackdepth +1 - self.mc.PUSH(gv_to_spill) - new_gv = IntVar(Register64(gv_to_spill.location.reg)) - gv_to_spill.location = Stack64(self.stackdepth) - return new_gv + assert isinstance(gv_to_spill.location, Register64) + # if the register contains a genCons + # it has not to be saved + if gv_to_spill.location.throw_away: + return gv_to_spill + else: + self.stackdepth = self.stackdepth +1 + self.mc.PUSH(gv_to_spill) + new_gv = IntVar(Register64(gv_to_spill.location.reg)) + gv_to_spill.location = Stack64(self.stackdepth) + return new_gv # FIXME: pushed values are not allways poped (if not TOS) def move_back_to_register(self, a_spilled_gv, dont_alloc): # if a_spilled_gv is the top of stack + gv_new = self.allocate_register(None, dont_alloc) if a_spilled_gv.location.offset == self.stackdepth: - gv_new = self.allocate_register(None, dont_alloc) self.mc.POP(gv_new) self.stackdepth = self.stackdepth -1 assert self.stackdepth >= 0 - #update all offsets - for i in range(len(self.known_gv)): - if isinstance(self.known_gv[i].location, Stack64): - self.known_gv[i].location.offset = self.known_gv[i].location.offset -1 - a_spilled_gv = gv_new - # TODO: free gv_new (no double values in known_gv) + a_spilled_gv.location = Register64(gv_new.location.reg) + self.known_gv.remove(gv_new) # TODO: look if there is a genVar with stackdepth # if not it has already been moved to a reg. # pop it or change the stackpointer @@ -465,9 +462,11 @@ else: # else access the memory # FIXME: if this genVar becomes the top of stack it will never be pushed - gv_new = self.allocate_register(None, dont_alloc) - self.mc.MOV(gv_new, IntVar(Stack64(8*(self.stackdepth-a_spilled_gv.location.offset)))) - a_spilled_gv = gv_new + self.mc.MOV(gv_new, IntVar(Stack64(8*(self.stackdepth-a_spilled_gv.location.offset))))#8=scale + #print "debug:",self.stackdepth + #print a_spilled_gv.location.offset + a_spilled_gv.location = Register64(gv_new.location.reg) + self.known_gv.remove(gv_new) return a_spilled_gv Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Wed Oct 15 16:33:51 2008 @@ -105,13 +105,16 @@ builder.end() return gv_bool_op -def make_cmp(rgenop, which_cmp, const=None): +def make_cmp(rgenop, which_cmp, const=None, switch_arg = False): sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) builder, gv_cmp, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "cmp") builder.start_writing() if not const == None: - gv_result = builder.genop2(which_cmp, gv_x, rgenop.genconst(const)) + if switch_arg: + gv_result = builder.genop2(which_cmp, rgenop.genconst(const), gv_x) + else: + gv_result = builder.genop2(which_cmp, gv_x, rgenop.genconst(const)) else: gv_result = builder.genop2(which_cmp, gv_x, gv_y) @@ -286,6 +289,22 @@ assert res == 0 res = fnptr(-4,0) assert res == 1 + cmp_function = make_cmp(self.RGenOp(), "int_lt", 4) + fnptr = self.cast(cmp_function,1) + res = fnptr(3) # 3<4 + assert res == 1 + res = fnptr(4) # 4<4 + assert res == 0 # False + cmp_function = make_cmp(self.RGenOp(), "int_lt", 3, switch_arg=True) + fnptr = self.cast(cmp_function,1) + res = fnptr(4) # 3<4 + assert res == 1 + res = fnptr(3) # 3<3 + assert res == 0 # False + cmp_function = make_cmp(self.RGenOp(), "int_lt", 1, switch_arg=True) + fnptr = self.cast(cmp_function,1) + res = fnptr(0) # 1<0 + assert res == 0 def test_less_or_equal(self): cmp_function = make_cmp(self.RGenOp(), "int_le") From fijal at codespeak.net Wed Oct 15 16:48:18 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 15 Oct 2008 16:48:18 +0200 (CEST) Subject: [pypy-svn] r59107 - pypy/branch/cbuild-refactor/pypy Message-ID: <20081015144818.7C1C616A488@codespeak.net> Author: fijal Date: Wed Oct 15 16:48:17 2008 New Revision: 59107 Modified: pypy/branch/cbuild-refactor/pypy/conftest.py Log: Add a possibility to set platform at test running time Modified: pypy/branch/cbuild-refactor/pypy/conftest.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/conftest.py (original) +++ pypy/branch/cbuild-refactor/pypy/conftest.py Wed Oct 15 16:48:17 2008 @@ -20,6 +20,13 @@ # Option = py.test.config.Option +def _set_platform(opt, opt_str, value, parser): + from pypy.config.translationoption import PLATFORMS + from pypy.translator.platform import set_platform + value = parser.rargs.pop(0) + if value not in PLATFORMS: + raise ValueError("%s not in %s" % (value, PLATFORMS)) + set_platform(value, None) option = py.test.config.addoptions("pypy options", Option('--view', action="store_true", dest="view", default=False, @@ -30,6 +37,9 @@ Option('--direct', action="store_true", default=False, dest="rundirect", help="run pexpect tests directly"), + Option('-P', '--platform', action="callback", + default="host", callback=_set_platform, + help="set up tests to use specified platform as compile/run target"), ) @@ -167,7 +177,7 @@ """ we take care of collecting classes both at app level and at interp-level (because we need to stick a space at the class) ourselves. - """ + """ def __init__(self, *args, **kwargs): if hasattr(sys, 'pypy_objspaceclass'): option.conf_iocapture = "sys" # pypy cannot do FD-based From fijal at codespeak.net Wed Oct 15 16:52:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 15 Oct 2008 16:52:33 +0200 (CEST) Subject: [pypy-svn] r59108 - pypy/branch/cbuild-refactor/pypy/rlib Message-ID: <20081015145233.D6A3A16A4B4@codespeak.net> Author: fijal Date: Wed Oct 15 16:52:33 2008 New Revision: 59108 Modified: pypy/branch/cbuild-refactor/pypy/rlib/libffi.py Log: leave a comment here. fixing requires a bit of carefulness Modified: pypy/branch/cbuild-refactor/pypy/rlib/libffi.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/rlib/libffi.py (original) +++ pypy/branch/cbuild-refactor/pypy/rlib/libffi.py Wed Oct 15 16:52:33 2008 @@ -16,6 +16,8 @@ import ctypes.util DEBUG = False # writes dlerror() messages to stderr +# XXX this need solving rather than hacking. We need to raise something else +# than OSError, something capable of delivering a message _MS_WINDOWS = os.name == "nt" _MAC_OS = sys.platform == "darwin" From arigo at codespeak.net Wed Oct 15 16:54:36 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 15 Oct 2008 16:54:36 +0200 (CEST) Subject: [pypy-svn] r59109 - in pypy/trunk/pypy: annotation objspace/flow rpython/lltypesystem rpython/ootypesystem rpython/test Message-ID: <20081015145436.2762816A4DA@codespeak.net> Author: arigo Date: Wed Oct 15 16:54:36 2008 New Revision: 59109 Modified: pypy/trunk/pypy/annotation/annrpython.py pypy/trunk/pypy/annotation/unaryop.py pypy/trunk/pypy/objspace/flow/objspace.py pypy/trunk/pypy/rpython/lltypesystem/rdict.py pypy/trunk/pypy/rpython/ootypesystem/rdict.py pypy/trunk/pypy/rpython/test/test_rdict.py Log: Test and fix for r_dict's "in" operator that can raise exceptions. Modified: pypy/trunk/pypy/annotation/annrpython.py ============================================================================== --- pypy/trunk/pypy/annotation/annrpython.py (original) +++ pypy/trunk/pypy/annotation/annrpython.py Wed Oct 15 16:54:36 2008 @@ -593,7 +593,9 @@ can_only_throw = annmodel.read_can_only_throw(binop, arg1, arg2) elif op.opname in annmodel.UNARY_OPERATIONS: arg1 = self.binding(op.args[0]) - unop = getattr(arg1, op.opname, None) + opname = op.opname + if opname == 'contains': opname = 'op_contains' + unop = getattr(arg1, opname, None) can_only_throw = annmodel.read_can_only_throw(unop, arg1) else: can_only_throw = None Modified: pypy/trunk/pypy/annotation/unaryop.py ============================================================================== --- pypy/trunk/pypy/annotation/unaryop.py (original) +++ pypy/trunk/pypy/annotation/unaryop.py Wed Oct 15 16:54:36 2008 @@ -182,6 +182,7 @@ def op_contains(obj, s_element): return s_Bool + op_contains.can_only_throw = [] def hint(self, *args_s): return self @@ -331,6 +332,7 @@ def op_contains(lst, s_element): lst.listdef.generalize(s_element) return s_Bool + op_contains.can_only_throw = [] def hint(lst, *args_s): hints = args_s[-1].const @@ -431,9 +433,15 @@ def method_clear(dct): pass + def _can_only_throw(dic, *ignore): + if dic1.dictdef.dictkey.custom_eq_hash: + return None # r_dict: can throw anything + return [] # else: no possible exception + def op_contains(dct, s_element): dct.dictdef.generalize_key(s_element) return s_Bool + op_contains.can_only_throw = _can_only_throw class __extend__(SomeString, Modified: pypy/trunk/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/pypy/objspace/flow/objspace.py Wed Oct 15 16:54:36 2008 @@ -493,7 +493,8 @@ # the annotator tests 'getitem': [IndexError, KeyError, Exception], 'setitem': [IndexError, KeyError, Exception], - 'delitem': [IndexError, KeyError, Exception], + 'delitem': [IndexError, KeyError, Exception], + 'contains': [Exception], # from an r_dict } def _add_exceptions(names, exc): Modified: pypy/trunk/pypy/rpython/lltypesystem/rdict.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rdict.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rdict.py Wed Oct 15 16:54:36 2008 @@ -331,6 +331,7 @@ def rtype_contains((r_dict, r_key), hop): v_dict, v_key = hop.inputargs(r_dict, r_dict.key_repr) + hop.exception_is_here() return hop.gendirectcall(ll_contains, v_dict, v_key) class __extend__(pairtype(DictRepr, DictRepr)): Modified: pypy/trunk/pypy/rpython/ootypesystem/rdict.py ============================================================================== --- pypy/trunk/pypy/rpython/ootypesystem/rdict.py (original) +++ pypy/trunk/pypy/rpython/ootypesystem/rdict.py Wed Oct 15 16:54:36 2008 @@ -227,7 +227,7 @@ def rtype_contains((r_dict, r_key), hop): vlist = hop.inputargs(r_dict, r_dict.key_repr) - hop.exception_cannot_occur() + hop.exception_is_here() return r_dict.send_message(hop, 'll_contains', v_args=vlist) def _get_call_vars(hop, r_func, arg, params_annotation): Modified: pypy/trunk/pypy/rpython/test/test_rdict.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rdict.py (original) +++ pypy/trunk/pypy/rpython/test/test_rdict.py Wed Oct 15 16:54:36 2008 @@ -3,6 +3,7 @@ from pypy.rpython import rint from pypy.rpython.lltypesystem import rdict, rstr from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin +from pypy.rlib.objectmodel import r_dict import py py.log.setconsumer("rtyper", py.log.STDOUT) @@ -496,6 +497,41 @@ res = self.interpret(g, [3]) assert res == 77 + def test_r_dict(self): + class FooError(Exception): + pass + def myeq(n, m): + return n == m + def myhash(n): + if n < 0: + raise FooError + return -n + def f(n): + d = r_dict(myeq, myhash) + for i in range(10): + d[i] = i*i + try: + value1 = d[n] + except FooError: + value1 = 99 + try: + value2 = n in d + except FooError: + value2 = 99 + try: + value3 = d[-n] + except FooError: + value3 = 99 + try: + value4 = (-n) in d + except FooError: + value4 = 99 + return (value1 * 1000000 + + value2 * 10000 + + value3 * 100 + + value4) + res = self.interpret(f, [5]) + assert res == 25019999 class TestLLtype(BaseTestRdict, LLRtypeMixin): def test_dict_but_not_with_char_keys(self): From fijal at codespeak.net Wed Oct 15 17:02:42 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 15 Oct 2008 17:02:42 +0200 (CEST) Subject: [pypy-svn] r59110 - in pypy/branch/cbuild-refactor/pypy: rlib translator/platform Message-ID: <20081015150242.E006F16A5B8@codespeak.net> Author: fijal Date: Wed Oct 15 17:02:42 2008 New Revision: 59110 Modified: pypy/branch/cbuild-refactor/pypy/rlib/libffi.py pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Log: Enough abstraction to have libffi platform-independent (at least a bit) Modified: pypy/branch/cbuild-refactor/pypy/rlib/libffi.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/rlib/libffi.py (original) +++ pypy/branch/cbuild-refactor/pypy/rlib/libffi.py Wed Oct 15 17:02:42 2008 @@ -19,25 +19,18 @@ # XXX this need solving rather than hacking. We need to raise something else # than OSError, something capable of delivering a message -_MS_WINDOWS = os.name == "nt" -_MAC_OS = sys.platform == "darwin" +from pypy.translator.platform import platform + +# maaaybe isinstance here would be better. Think +_MS_WINDOWS = platform.name == "win32" +_MAC_OS = platform.name == "darwin" if _MS_WINDOWS: from pypy.rlib import rwin32 if not _MS_WINDOWS: includes = ['dlfcn.h', 'ffi.h'] - include_dirs = [] - if _MAC_OS: - pot_incl = py.path.local('/usr/include/ffi') - else: - pot_incl = py.path.local('/usr/include/libffi') - if pot_incl.check(): - include_dirs.append(str(pot_incl)) - lib_dirs = [] - pot_lib = py.path.local('/usr/lib/libffi') - if pot_lib.check(): - lib_dirs.append(str(pot_lib)) + include_dirs = platform.include_dirs_for_libffi() if _MAC_OS: pre_include_bits = ['#define MACOSX'] @@ -47,8 +40,8 @@ pre_include_bits = pre_include_bits, includes = includes, libraries = ['ffi', 'dl'], - include_dirs = include_dirs, - library_dirs = lib_dirs, + include_dirs = platform.include_dirs_for_libffi(), + library_dirs = platform.library_dirs_for_libffi(), ) else: libffidir = py.path.local(pypydir).join('translator', 'c', 'src', 'libffi_msvc') Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Wed Oct 15 17:02:42 2008 @@ -24,6 +24,8 @@ return "" % (self.returncode,) class Platform(object): + name = "abstract platform" + def __init__(self, cc): self.cc = cc @@ -49,6 +51,14 @@ return (self.__class__ is other.__class__ and self.__dict__ == other.__dict__) + # below are some detailed informations for platforms + + def include_dirs_for_libffi(self): + raise NotImplementedError("Needs to be overwritten") + + def library_dirs_for_libffi(self): + raise NotImplementedError("Needs to be overwritten") + def check___thread(self): return True Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Wed Oct 15 17:02:42 2008 @@ -3,6 +3,8 @@ from pypy.translator.platform import linux # xxx class Darwin(linux.Linux): # xxx + name = "darwin" + link_flags = [] cflags = ['-O3', '-fomit-frame-pointer'] # -mdynamic-no-pic for standalone @@ -12,3 +14,9 @@ def _args_for_shared(self, args): return ['-bundle', '-undefined', 'dynamic_lookup'] + args + + def include_dirs_for_libffi(self): + return ['/usr/include/ffi'] + + def library_dirs_for_libffi(self): + return [] Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Wed Oct 15 17:02:42 2008 @@ -108,6 +108,8 @@ f.close() class Linux(Platform): + name = "linux" + link_flags = ['-pthread'] cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] so_ext = 'so' @@ -269,3 +271,9 @@ if len(stderrlines) > 5: log.ERROR('...') raise CompilationError(stdout, stderr) + + def include_dirs_for_libffi(self): + return ['/usr/include/libffi'] + + def library_dirs_for_libffi(self): + return ['/usr/lib/libffi'] Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Wed Oct 15 17:02:42 2008 @@ -8,6 +8,8 @@ py.test.skip("No scratchbox detected") class Maemo(Linux): + name = "maemo" + available_includedirs = ['/usr/include', '/tmp'] copied_cache = {} @@ -65,3 +67,10 @@ env) return ExecutionResult(returncode, stdout, stderr) + def include_dirs_for_libffi(self): + # insanely obscure dir + return ['/usr/include/arm-linux-gnueabi/'] + + def library_dirs_for_libffi(self): + # on the other hand, library lands in usual place... + return [] From arigo at codespeak.net Wed Oct 15 17:13:24 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 15 Oct 2008 17:13:24 +0200 (CEST) Subject: [pypy-svn] r59111 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081015151324.38C7D16A5E1@codespeak.net> Author: arigo Date: Wed Oct 15 17:13:23 2008 New Revision: 59111 Modified: pypy/trunk/pypy/objspace/std/sliceobject.py pypy/trunk/pypy/objspace/std/test/test_sliceobject.py Log: (antocuni, arigo) Fix an issue shown by (e.g.) test_iterobject.py. The fix is to be as sane as possible in the return value of normalize_simple_slice(). Modified: pypy/trunk/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/sliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/sliceobject.py Wed Oct 15 17:13:23 2008 @@ -82,18 +82,18 @@ def normalize_simple_slice(space, length, w_start, w_stop): """Helper for the {get,set,del}slice multimethod implementations.""" # this returns a pair (start, stop) which is usable for slicing - # a sequence of the given length in an RPython-friendly way, i.e. - # guaranteeing that: - # * 0 <= start <= length - # * start <= stop + # a sequence of the given length in the most friendly way, i.e. + # guaranteeing that 0 <= start <= stop <= length. start = space.int_w(w_start) stop = space.int_w(w_stop) - if start > length: - start = length if start < 0: start = 0 if stop < start: stop = start + if stop > length: + stop = length + if start > length: + start = length return start, stop Modified: pypy/trunk/pypy/objspace/std/test/test_sliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_sliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_sliceobject.py Wed Oct 15 17:13:23 2008 @@ -37,8 +37,7 @@ for stop in range(-2*length-2, 2*length+3): mystart, mystop = normalize_simple_slice(space, length, w(start), w(stop)) - assert 0 <= mystart <= length - assert mystart <= mystop + assert 0 <= mystart <= mystop <= length assert (getslice(length, start, stop) == getslice(length, mystart, mystop)) From fijal at codespeak.net Wed Oct 15 17:51:36 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 15 Oct 2008 17:51:36 +0200 (CEST) Subject: [pypy-svn] r59112 - in pypy/branch/cbuild-refactor/pypy: config translator/c translator/c/test translator/platform translator/platform/test translator/tool Message-ID: <20081015155136.C845D16A122@codespeak.net> Author: fijal Date: Wed Oct 15 17:51:34 2008 New Revision: 59112 Added: pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py (contents, props changed) pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_distutils.py (contents, props changed) pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (contents, props changed) Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/c/test/test_genc.py pypy/branch/cbuild-refactor/pypy/translator/c/test/test_typed.py pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Log: Delete as much stuff as possible from genc. Create distutils platform, which is a default if we don't know what to do. Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/config/translationoption.py (original) +++ pypy/branch/cbuild-refactor/pypy/config/translationoption.py Wed Oct 15 17:51:34 2008 @@ -13,6 +13,8 @@ PLATFORMS = [ 'maemo', + 'host', + 'distutils', ] translation_optiondescription = OptionDescription( @@ -360,13 +362,15 @@ set_platform(config.translation.platform, config.translation.cc) def get_platform(config): - # XXX use config opt = config.translation.platform if opt == 'maemo': from pypy.translator.platform.maemo import Maemo return Maemo(config.translation.cc) elif opt == 'host': from pypy.translator.platform import host - return host + return host.__class__(config.translation.cc) + elif opt == 'distutils': + from pypy.translator.platform.distutils_platform import DistutilsPlatform + return DistutilsPlatform(config.translation.cc) else: raise ValueError(opt) Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Wed Oct 15 17:51:34 2008 @@ -6,8 +6,7 @@ from pypy.translator.c.extfunc import pre_include_code_lines from pypy.translator.llsupport.wrapper import new_wrapper from pypy.translator.gensupp import uniquemodulename, NameManager -from pypy.translator.tool.cbuild import so_ext, ExternalCompilationInfo -from pypy.translator.tool.cbuild import import_module_from_directory +from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator.tool.cbuild import check_under_under_thread from pypy.rpython.lltypesystem import lltype from pypy.tool.udir import udir @@ -16,6 +15,15 @@ from pypy.rpython.typesystem import getfunctionptr from pypy.translator.c import gc +def import_module_from_directory(dir, modname): + file, pathname, description = imp.find_module(modname, [str(dir)]) + try: + mod = imp.load_module(modname, file, pathname, description) + finally: + if file: + file.close() + return mod + class ProfOpt(object): #XXX assuming gcc style flags for now name = "profopt" @@ -315,7 +323,7 @@ _rpython_startup = _lib.RPython_StartupCode _rpython_startup() -""" % {'so_name': self.c_source_filename.new(ext=so_ext), +""" % {'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) Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_genc.py Wed Oct 15 17:51:34 2008 @@ -9,7 +9,6 @@ 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.tool.cbuild import make_module_from_c from pypy.translator.gensupp import uniquemodulename from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.interactive import Translation Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_typed.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_typed.py Wed Oct 15 17:51:34 2008 @@ -10,11 +10,6 @@ from pypy.translator.translator import TranslationContext from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask -# XXX this tries to make compiling faster for full-scale testing -from pypy.translator.tool import cbuild -cbuild.enable_fast_compilation() - - class CompilationTestCase: def annotatefunc(self, func, argtypes=None): Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Wed Oct 15 17:51:34 2008 @@ -3,12 +3,28 @@ platform. """ -import sys, py +import sys, py, os from pypy.tool.ansi_print import ansi_log log = py.log.Producer("platform") py.log.setconsumer("platform", ansi_log) +from subprocess import PIPE, Popen + +def _run_subprocess(executable, args, env=None): + if isinstance(args, str): + args = str(executable) + ' ' + args + shell = True + else: + if args is None: + args = [str(executable)] + else: + args = [str(executable)] + args + shell = False + pipe = Popen(args, stdout=PIPE, stderr=PIPE, shell=shell, env=env) + stdout, stderr = pipe.communicate() + return pipe.returncode, stdout, stderr + class CompilationError(Exception): def __init__(self, out, err): self.out = out @@ -32,8 +48,10 @@ def compile(self, cfiles, eci, outputfilename=None, standalone=True): raise NotImplementedError("Pure abstract baseclass") - def execute(self, file_to_exec, args=None, env=None): - raise NotImplementedError("Pure abstract baseclass") + def execute(self, executable, args=None, env=None): + returncode, stdout, stderr = _run_subprocess(str(executable), args, + env) + return ExecutionResult(returncode, stdout, stderr) def gen_makefile(self, cfiles, eci, exe_name=None, path=None): raise NotImplementedError("Pure abstract baseclass") @@ -69,9 +87,13 @@ elif sys.platform == 'darwin': from pypy.translator.platform.darwin import Darwin host = Darwin() +elif os.name == 'nt': + from pypy.translator.platform.windows import Windows + host = Windows() else: - xxx - + # pray + from pypy.translator.platform.distutils_platform import DistutilsPlatform + host = DistutilsPlatform() platform = host @@ -83,6 +105,9 @@ elif new_platform == 'maemo': from pypy.translator.platform.maemo import Maemo platform = Maemo(cc) + elif new_platform == 'distutils': + from pypy.translator.platform.distutils_platform import DistutilsPlatform + platform = DistutilsPlatform() else: raise NotImplementedError("platform = %s" % (new_platform,)) Added: pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py Wed Oct 15 17:51:34 2008 @@ -0,0 +1,153 @@ + +from pypy.translator.platform import Platform, log, CompilationError +import py, sys, os +from pypy.translator.tool import stdoutcapture + +def log_spawned_cmd(spawn): + def spawn_and_log(cmd, *args, **kwds): + log.execute(' '.join(cmd)) + return spawn(cmd, *args, **kwds) + return spawn_and_log + +CFLAGS = ['-O3'] + +class DistutilsPlatform(Platform): + """ This is a generic distutils platform. I hope it'll go away at some + point soon completely + """ + def __init__(self, cc=None): + self.cc = cc + + def _ensure_correct_math(self): + if self.name != 'win32': + return # so far + from distutils import sysconfig + gcv = sysconfig.get_config_vars() + opt = gcv.get('OPT') # not always existent + if opt and '/Op' not in opt: + opt += '/Op' + gcv['OPT'] = opt + + def compile(self, cfilenames, eci, outputfilename=None, standalone=True): + self._ensure_correct_math() + self.cfilenames = cfilenames + if standalone: + ext = '' + else: + ext = so_ext + self.standalone = standalone + self.libraries = list(eci.libraries) + self.include_dirs = list(eci.include_dirs) + self.library_dirs = list(eci.library_dirs) + self.compile_extra = list(eci.compile_extra) + self.link_extra = list(eci.link_extra) + self.frameworks = list(eci.frameworks) + if not self.name in ('win32', 'darwin'): # xxx + if 'm' not in self.libraries: + self.libraries.append('m') + self.compile_extra += CFLAGS + ['-fomit-frame-pointer'] + if 'pthread' not in self.libraries: + self.libraries.append('pthread') + if self.name != 'sunos5': + self.compile_extra += ['-pthread'] + self.link_extra += ['-pthread'] + else: + self.compile_extra += ['-pthreads'] + self.link_extra += ['-lpthread'] + if self.name == 'win32': + self.link_extra += ['/DEBUG'] # generate .pdb file + if self.name == 'darwin': + # support Fink & Darwinports + for s in ('/sw/', '/opt/local/'): + if s + 'include' not in self.include_dirs and \ + os.path.exists(s + 'include'): + self.include_dirs.append(s + 'include') + if s + 'lib' not in self.library_dirs and \ + os.path.exists(s + 'lib'): + self.library_dirs.append(s + 'lib') + self.compile_extra += CFLAGS + ['-fomit-frame-pointer'] + for framework in self.frameworks: + self.link_extra += ['-framework', framework] + + if outputfilename is None: + self.outputfilename = py.path.local(cfilenames[0]).new(ext=ext) + else: + self.outputfilename = py.path.local(outputfilename) + self.eci = eci + import distutils.errors + basename = self.outputfilename.new(ext='') + data = '' + try: + saved_environ = os.environ.copy() + try: + c = stdoutcapture.Capture(mixed_out_err = True) + self._build() + finally: + # workaround for a distutils bugs where some env vars can + # become longer and longer every time it is used + for key, value in saved_environ.items(): + if os.environ.get(key) != value: + os.environ[key] = value + foutput, foutput = c.done() + data = foutput.read() + if data: + fdump = basename.new(ext='errors').open("w") + fdump.write(data) + fdump.close() + except (distutils.errors.CompileError, + distutils.errors.LinkError), e: + data = data.rstrip() + if data: + data += '\n' + data += str(e) + raise CompilationError('', data) + except: + print >>sys.stderr, data + raise + return self.outputfilename + + def _build(self): + from distutils.ccompiler import new_compiler + from distutils import sysconfig + compiler = new_compiler(force=1) + if self.cc is not None: + for c in '''compiler compiler_so compiler_cxx + linker_exe linker_so'''.split(): + compiler.executables[c][0] = self.cc + if not self.standalone: + sysconfig.customize_compiler(compiler) # XXX + compiler.spawn = log_spawned_cmd(compiler.spawn) + objects = [] + for cfile in self.cfilenames: + cfile = py.path.local(cfile) + compile_extra = self.compile_extra[:] + # -frandom-seed is only to try to be as reproducable as possible + if 0 and self.fix_gcc_random_seed: + compile_extra.append('-frandom-seed=%s' % (cfile.basename,)) + # XXX horrible workaround for a bug of profiling in gcc on + # OS X with functions containing a direct call to fork() + if '/*--no-profiling-for-this-file!--*/' in cfile.read(): + compile_extra = [arg for arg in compile_extra + if not arg.startswith('-fprofile-')] + + old = cfile.dirpath().chdir() + try: + res = compiler.compile([cfile.basename], + include_dirs=self.eci.include_dirs, + extra_preargs=compile_extra) + assert len(res) == 1 + cobjfile = py.path.local(res[0]) + assert cobjfile.check() + objects.append(str(cobjfile)) + finally: + old.chdir() + + if self.standalone: + cmd = compiler.link_executable + else: + cmd = compiler.link_shared_object + cmd(objects, str(self.outputfilename), + libraries=self.eci.libraries, + extra_preargs=self.link_extra, + library_dirs=self.eci.library_dirs) + Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Wed Oct 15 17:51:34 2008 @@ -1,24 +1,9 @@ import py, os from pypy.translator.platform import Platform, CompilationError, ExecutionResult -from pypy.translator.platform import log -from subprocess import PIPE, Popen +from pypy.translator.platform import log, _run_subprocess from pypy.tool import autopath -def _run_subprocess(executable, args, env=None): - if isinstance(args, str): - args = str(executable) + ' ' + args - shell = True - else: - if args is None: - args = [str(executable)] - else: - args = [str(executable)] + args - shell = False - pipe = Popen(args, stdout=PIPE, stderr=PIPE, shell=shell, env=env) - stdout, stderr = pipe.communicate() - return pipe.returncode, stdout, stderr - class Definition(object): def __init__(self, name, value): self.name = name @@ -192,11 +177,6 @@ self._execute_c_compiler(cc, args, exe_name) return exe_name - def execute(self, executable, args=None, env=None): - returncode, stdout, stderr = _run_subprocess(str(executable), args, - env) - return ExecutionResult(returncode, stdout, stderr) - def gen_makefile(self, cfiles, eci, exe_name=None, path=None): cfiles = [py.path.local(f) for f in cfiles] cfiles += [py.path.local(f) for f in eci.separate_module_files] Added: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_distutils.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_distutils.py Wed Oct 15 17:51:34 2008 @@ -0,0 +1,10 @@ + +from pypy.translator.platform.test.test_platform import TestPlatform as BasicTest +from pypy.translator.platform.distutils_platform import DistutilsPlatform +import py + +class TestDistutils(BasicTest): + platform = DistutilsPlatform() + + def test_nice_errors(self): + py.test.skip("Unsupported") Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Wed Oct 15 17:51:34 2008 @@ -1,7 +1,8 @@ import py, sys from pypy.tool.udir import udir -from pypy.translator.platform import host, CompilationError, Platform +from pypy.translator.platform import CompilationError, Platform +from pypy.translator.platform import host from pypy.translator.tool.cbuild import ExternalCompilationInfo class TestPlatform(object): Added: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Wed Oct 15 17:51:34 2008 @@ -0,0 +1,7 @@ + +from pypy.translator.platform.distutils_platform import DistutilsPlatform + +class Windows(DistutilsPlatform): + name = "win32" + so_ext = 'dll' + Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Wed Oct 15 17:51:34 2008 @@ -1,7 +1,6 @@ import autopath import os, sys, inspect, re, imp -from pypy.translator.tool import stdoutcapture from pypy.tool.autopath import pypydir from pypy.translator.platform import host @@ -280,227 +279,6 @@ d['separate_module_sources'] = () return ExternalCompilationInfo(**d) -if sys.platform == 'win32': - so_ext = '.dll' -else: - so_ext = '.so' - -def compiler_command(): - # e.g. for tcc, you might set this to - # "tcc -shared -o %s.so %s.c" - return os.getenv('PYPY_CC') - -def enable_fast_compilation(): - if sys.platform == 'win32': - dash = '/' - else: - dash = '-' - from distutils import sysconfig - gcv = sysconfig.get_config_vars() - opt = gcv.get('OPT') # not always existent - if opt: - opt = re.sub('%sO\d+' % dash, '%sO0' % dash, opt) - else: - opt = '%sO0' % dash - gcv['OPT'] = opt - -def ensure_correct_math(): - if sys.platform != 'win32': - return # so far - from distutils import sysconfig - gcv = sysconfig.get_config_vars() - opt = gcv.get('OPT') # not always existent - if opt and '/Op' not in opt: - opt += '/Op' - gcv['OPT'] = opt - -def next_unique_name(modbasename, tmpdir): - modname = modbasename - while 1: - if not tmpdir.join(modname + so_ext).check(): - break - num += 1 - modname = '%s_%d' % (modbasename, num) - return modname - -def compile_c_module(cfiles, modbasename, eci, tmpdir=None): - eci = eci.convert_sources_to_files() - cfiles.extend(eci.separate_module_files) - compiler = CCompiler(cfiles, eci, standalone=False) - compiler.build() - return str(compiler.outputfilename) - -def make_module_from_c(cfile, eci): - cfile = py.path.local(cfile) - modname = cfile.purebasename - compile_c_module([cfile], modname, eci) - return import_module_from_directory(cfile.dirpath(), modname) - -def import_module_from_directory(dir, modname): - file, pathname, description = imp.find_module(modname, [str(dir)]) - try: - mod = imp.load_module(modname, file, pathname, description) - finally: - if file: - file.close() - return mod - - -def log_spawned_cmd(spawn): - def spawn_and_log(cmd, *args, **kwds): - log.execute(' '.join(cmd)) - return spawn(cmd, *args, **kwds) - return spawn_and_log - - -class CompilationError(Exception): - pass - -class CCompiler: - fix_gcc_random_seed = False - - def __init__(self, cfilenames, eci, outputfilename=None, - compiler_exe=None, profbased=None, standalone=True): - XXX - self.cfilenames = cfilenames - if standalone: - ext = '' - else: - ext = so_ext - self.standalone = standalone - self.libraries = list(eci.libraries) - self.include_dirs = list(eci.include_dirs) - self.library_dirs = list(eci.library_dirs) - self.compile_extra = list(eci.compile_extra) - self.link_extra = list(eci.link_extra) - self.frameworks = list(eci.frameworks) - if compiler_exe is not None: - self.compiler_exe = compiler_exe - else: - self.compiler_exe = eci.platform.get_compiler() - self.profbased = profbased - if not sys.platform in ('win32', 'darwin'): # xxx - if 'm' not in self.libraries: - self.libraries.append('m') - self.compile_extra += CFLAGS + ['-fomit-frame-pointer'] - if 'pthread' not in self.libraries: - self.libraries.append('pthread') - if sys.platform != 'sunos5': - self.compile_extra += ['-pthread'] - self.link_extra += ['-pthread'] - else: - self.compile_extra += ['-pthreads'] - self.link_extra += ['-lpthread'] - if sys.platform == 'win32': - self.link_extra += ['/DEBUG'] # generate .pdb file - if sys.platform == 'darwin': - # support Fink & Darwinports - for s in ('/sw/', '/opt/local/'): - if s + 'include' not in self.include_dirs and \ - os.path.exists(s + 'include'): - self.include_dirs.append(s + 'include') - if s + 'lib' not in self.library_dirs and \ - os.path.exists(s + 'lib'): - self.library_dirs.append(s + 'lib') - self.compile_extra += CFLAGS + ['-fomit-frame-pointer'] - for framework in self.frameworks: - self.link_extra += ['-framework', framework] - - if outputfilename is None: - self.outputfilename = py.path.local(cfilenames[0]).new(ext=ext) - else: - self.outputfilename = py.path.local(outputfilename) - self.eci = eci - - def build(self, noerr=False): - import distutils.errors - basename = self.outputfilename.new(ext='') - data = '' - try: - saved_environ = os.environ.copy() - try: - c = stdoutcapture.Capture(mixed_out_err = True) - if self.profbased is None: - self._build() - else: - ProfDriver, args = self.profbased - profdrv = ProfDriver(self) - dolog = getattr(log, profdrv.name) - dolog(args) - profdrv.first() - dolog('Gathering profile data from: %s %s' % ( - str(self.outputfilename), args)) - profdrv.probe(str(self.outputfilename),args) - profdrv.after() - finally: - # workaround for a distutils bugs where some env vars can - # become longer and longer every time it is used - for key, value in saved_environ.items(): - if os.environ.get(key) != value: - os.environ[key] = value - foutput, foutput = c.done() - data = foutput.read() - if data: - fdump = basename.new(ext='errors').open("w") - fdump.write(data) - fdump.close() - except (distutils.errors.CompileError, - distutils.errors.LinkError), e: - data = data.rstrip() - if data: - data += '\n' - data += str(e) - raise CompilationError(data) - except: - if not noerr: - print >>sys.stderr, data - raise - - def _build(self): - from distutils.ccompiler import new_compiler - from distutils import sysconfig - compiler = new_compiler(force=1) - if self.compiler_exe is not None: - for c in '''compiler compiler_so compiler_cxx - linker_exe linker_so'''.split(): - compiler.executables[c][0] = self.compiler_exe - if not self.standalone: - sysconfig.customize_compiler(compiler) # XXX - compiler.spawn = log_spawned_cmd(compiler.spawn) - objects = [] - for cfile in self.cfilenames: - cfile = py.path.local(cfile) - compile_extra = self.compile_extra[:] - # -frandom-seed is only to try to be as reproducable as possible - if self.fix_gcc_random_seed: - compile_extra.append('-frandom-seed=%s' % (cfile.basename,)) - # XXX horrible workaround for a bug of profiling in gcc on - # OS X with functions containing a direct call to fork() - if '/*--no-profiling-for-this-file!--*/' in cfile.read(): - compile_extra = [arg for arg in compile_extra - if not arg.startswith('-fprofile-')] - - old = cfile.dirpath().chdir() - try: - res = compiler.compile([cfile.basename], - include_dirs=self.eci.include_dirs, - extra_preargs=compile_extra) - assert len(res) == 1 - cobjfile = py.path.local(res[0]) - assert cobjfile.check() - objects.append(str(cobjfile)) - finally: - old.chdir() - - if self.standalone: - cmd = compiler.link_executable - else: - cmd = compiler.link_shared_object - cmd(objects, str(self.outputfilename), - libraries=self.eci.libraries, - extra_preargs=self.link_extra, - library_dirs=self.eci.library_dirs) - def check_under_under_thread(): xxx from pypy.tool.udir import udir From arigo at codespeak.net Wed Oct 15 18:12:03 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 15 Oct 2008 18:12:03 +0200 (CEST) Subject: [pypy-svn] r59113 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081015161203.AD65B16A5E7@codespeak.net> Author: arigo Date: Wed Oct 15 18:12:03 2008 New Revision: 59113 Modified: pypy/trunk/pypy/objspace/std/ropeunicodeobject.py pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/test/test_stringobject.py Log: (cfbolz, arigo) Fix a failing test. Add another failing test and skip it for now. Modified: pypy/trunk/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeunicodeobject.py Wed Oct 15 18:12:03 2008 @@ -722,7 +722,11 @@ oldlength = old.length() if not oldlength: parts = _split_into_chars(self, maxsplit) - return W_RopeUnicodeObject(rope.join(w_new._node, parts)) + try: + return W_RopeUnicodeObject(rope.join(w_new._node, parts)) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("string too long")) substrings = rope.split(self, old, maxsplit) if not substrings: return w_self.create_if_subclassed() @@ -790,7 +794,11 @@ _tabindent(last, tabsize))) last = splitted[i] expanded.append(last) - return W_RopeUnicodeObject(rope.rebalance(expanded)) + try: + return W_RopeUnicodeObject(rope.rebalance(expanded)) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("string too long")) def unicode_translate__RopeUnicode_ANY(space, w_self, w_table): self = w_self._node Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Wed Oct 15 18:12:03 2008 @@ -665,7 +665,7 @@ u_expanded = "" if u_self: - split = u_self.split("\t") #XXX use pypy split + split = u_self.split("\t") u_expanded =oldtoken = split.pop(0) for token in split: Modified: pypy/trunk/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_stringobject.py Wed Oct 15 18:12:03 2008 @@ -396,6 +396,12 @@ assert 'xy'.expandtabs() =='xy' assert ''.expandtabs() =='' + def test_expandtabs_overflows_gracefully(self): + skip("XXX fix me") + import sys + if sys.maxint > (1 << 32): + skip("Wrong platform") + raises(OverflowError, 't\tt\t'.expandtabs, sys.maxint) def test_splitlines(self): s = "" From arigo at codespeak.net Wed Oct 15 18:46:58 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 15 Oct 2008 18:46:58 +0200 (CEST) Subject: [pypy-svn] r59114 - pypy/trunk/pypy/objspace/std Message-ID: <20081015164658.CD45516A5A2@codespeak.net> Author: arigo Date: Wed Oct 15 18:46:56 2008 New Revision: 59114 Modified: pypy/trunk/pypy/objspace/std/sliceobject.py Log: Translation fix. Modified: pypy/trunk/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/sliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/sliceobject.py Wed Oct 15 18:46:56 2008 @@ -86,6 +86,7 @@ # guaranteeing that 0 <= start <= stop <= length. start = space.int_w(w_start) stop = space.int_w(w_stop) + assert length >= 0 if start < 0: start = 0 if stop < start: From fijal at codespeak.net Wed Oct 15 23:51:20 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 15 Oct 2008 23:51:20 +0200 (CEST) Subject: [pypy-svn] r59118 - pypy/branch/cbuild-refactor/pypy/rlib/rsdl Message-ID: <20081015215120.6CF1C16A2D5@codespeak.net> Author: fijal Date: Wed Oct 15 23:51:19 2008 New Revision: 59118 Modified: pypy/branch/cbuild-refactor/pypy/rlib/rsdl/eci.py Log: Fix import Modified: pypy/branch/cbuild-refactor/pypy/rlib/rsdl/eci.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/rlib/rsdl/eci.py (original) +++ pypy/branch/cbuild-refactor/pypy/rlib/rsdl/eci.py Wed Oct 15 23:51:19 2008 @@ -1,5 +1,5 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.translator.tool.cbuild import CompilationError +from pypy.translator.platform import CompilationError import py import sys From fijal at codespeak.net Wed Oct 15 23:56:17 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 15 Oct 2008 23:56:17 +0200 (CEST) Subject: [pypy-svn] r59119 - pypy/branch/cbuild-refactor/pypy/translator/c/test Message-ID: <20081015215617.CFF7116A55E@codespeak.net> Author: fijal Date: Wed Oct 15 23:56:17 2008 New Revision: 59119 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_rtagged.py Log: fix test Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_rtagged.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_rtagged.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_rtagged.py Wed Oct 15 23:56:17 2008 @@ -69,7 +69,7 @@ def test_tagged_boehm(): t = Translation(entry_point, standalone=True, gc='boehm') try: - exename = t.compile_c() + exename = str(t.compile_c()) finally: if conftest.option.view: t.view() From fijal at codespeak.net Thu Oct 16 00:04:30 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 00:04:30 +0200 (CEST) Subject: [pypy-svn] r59121 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test Message-ID: <20081015220430.093DF169FEC@codespeak.net> Author: fijal Date: Thu Oct 16 00:04:30 2008 New Revision: 59121 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Log: Some support for makefiles on maemo. Note that makefile is supposed to be run from outside scratchbox. I'm completely unsure whether this approach make any sense, experimenting. Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Thu Oct 16 00:04:30 2008 @@ -1,7 +1,8 @@ import py -from pypy.translator.platform.linux import Linux, _run_subprocess +from pypy.translator.platform.linux import Linux, _run_subprocess, GnuMakefile from pypy.translator.platform import ExecutionResult, log from pypy.tool.udir import udir +from pypy.tool import autopath def check_scratchbox(): if not py.path.local('/scratchbox/login').check(): @@ -74,3 +75,55 @@ def library_dirs_for_libffi(self): # on the other hand, library lands in usual place... return [] + + + def gen_makefile(self, cfiles, eci, exe_name=None, path=None): + cfiles = [py.path.local(f) for f in cfiles] + cfiles += [py.path.local(f) for f in eci.separate_module_files] + + if path is None: + path = cfiles[0].dirpath() + + pypypath = py.path.local(autopath.pypydir) + + if exe_name is None: + exe_name = cfiles[0].new(ext='') + + m = GnuMakefile(path) + m.exe_name = exe_name + m.eci = eci + + rel_cfiles = [str(cfile) for cfile in cfiles] + rel_ofiles = [rel_cfile[:-2]+'.o' for rel_cfile in rel_cfiles] + m.cfiles = rel_cfiles + + rel_includedirs = [str(incldir) for incldir in + self._preprocess_dirs(eci.include_dirs)] + + m.comment('automatically generated makefile') + definitions = [ + ('TARGET', str(exe_name)), + ('DEFAULT_TARGET', '$(TARGET)'), + ('SOURCES', rel_cfiles), + ('OBJECTS', rel_ofiles), + ('LIBS', self._libs(eci.libraries)), + ('LIBDIRS', self._libdirs(eci.library_dirs)), + ('INCLUDEDIRS', self._includedirs(rel_includedirs)), + ('CFLAGS', self.cflags + list(eci.compile_extra)), + ('LDFLAGS', self.link_flags + list(eci.link_extra)), + ('CC', '/scratchbox/login ' + self.cc) + ] + for args in definitions: + m.definition(*args) + + rules = [ + ('all', '$(DEFAULT_TARGET)', []), + ('$(TARGET)', '$(OBJECTS)', '$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS)'), + ('%.o', '%.c', '$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)'), + ] + + for rule in rules: + m.rule(*rule) + + return m + Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Thu Oct 16 00:04:30 2008 @@ -9,24 +9,36 @@ assert res.out == '42 24\n' res = host.execute('echo', ['42', '24']) assert res.out == '42 24\n' + +class TestMakefile(object): + platform = host + strict_on_stderr = True -def test_simple_makefile(): - tmpdir = udir.join('simple_makefile').ensure(dir=1) - cfile = tmpdir.join('test_simple_enough.c') - cfile.write(''' - #include - int main() - { - printf("42\\n"); - return 0; - } - ''') - mk = host.gen_makefile([cfile], ExternalCompilationInfo(), - path=tmpdir) - mk.write() - host.execute_makefile(mk) - res = host.execute(tmpdir.join('test_simple_enough')) - assert res.out == '42\n' - assert res.err == '' - assert res.returncode == 0 + def test_simple_makefile(self): + tmpdir = udir.join('simple_makefile' + self.__class__.__name__).ensure(dir=1) + cfile = tmpdir.join('test_simple_enough.c') + cfile.write(''' + #include + int main() + { + printf("42\\n"); + return 0; + } + ''') + mk = self.platform.gen_makefile([cfile], ExternalCompilationInfo(), + path=tmpdir) + mk.write() + self.platform.execute_makefile(mk) + res = self.platform.execute(tmpdir.join('test_simple_enough')) + assert res.out == '42\n' + if self.strict_on_stderr: + assert res.err == '' + assert res.returncode == 0 +class TestMaemo(TestMakefile): + strict_on_stderr = False + + def setup_class(cls): + from pypy.translator.platform.maemo import check_scratchbox, Maemo + check_scratchbox() + cls.platform = Maemo() From fijal at codespeak.net Thu Oct 16 00:08:11 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 00:08:11 +0200 (CEST) Subject: [pypy-svn] r59122 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081015220811.DEC0916A1F8@codespeak.net> Author: fijal Date: Thu Oct 16 00:08:11 2008 New Revision: 59122 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Log: Hack differently. Invoke make from inside scratchbox. Looks a bit cleaner IMO Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Thu Oct 16 00:08:11 2008 @@ -242,15 +242,7 @@ path = path_to_makefile log.execute('make in %s' % (path,)) returncode, stdout, stderr = _run_subprocess('make', ['-C', str(path)]) - if returncode != 0: - errorfile = path.join('make.errors') - errorfile.write(stderr) - stderrlines = stderr.splitlines() - for line in stderrlines[:5]: - log.ERROR(line) - if len(stderrlines) > 5: - log.ERROR('...') - raise CompilationError(stdout, stderr) + self._handle_error(returncode, stdout, stderr, path.join('make')) def include_dirs_for_libffi(self): return ['/usr/include/libffi'] Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Thu Oct 16 00:08:11 2008 @@ -76,54 +76,11 @@ # on the other hand, library lands in usual place... return [] - - def gen_makefile(self, cfiles, eci, exe_name=None, path=None): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] - - if path is None: - path = cfiles[0].dirpath() - - pypypath = py.path.local(autopath.pypydir) - - if exe_name is None: - exe_name = cfiles[0].new(ext='') - - m = GnuMakefile(path) - m.exe_name = exe_name - m.eci = eci - - rel_cfiles = [str(cfile) for cfile in cfiles] - rel_ofiles = [rel_cfile[:-2]+'.o' for rel_cfile in rel_cfiles] - m.cfiles = rel_cfiles - - rel_includedirs = [str(incldir) for incldir in - self._preprocess_dirs(eci.include_dirs)] - - m.comment('automatically generated makefile') - definitions = [ - ('TARGET', str(exe_name)), - ('DEFAULT_TARGET', '$(TARGET)'), - ('SOURCES', rel_cfiles), - ('OBJECTS', rel_ofiles), - ('LIBS', self._libs(eci.libraries)), - ('LIBDIRS', self._libdirs(eci.library_dirs)), - ('INCLUDEDIRS', self._includedirs(rel_includedirs)), - ('CFLAGS', self.cflags + list(eci.compile_extra)), - ('LDFLAGS', self.link_flags + list(eci.link_extra)), - ('CC', '/scratchbox/login ' + self.cc) - ] - for args in definitions: - m.definition(*args) - - rules = [ - ('all', '$(DEFAULT_TARGET)', []), - ('$(TARGET)', '$(OBJECTS)', '$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS)'), - ('%.o', '%.c', '$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)'), - ] - - for rule in rules: - m.rule(*rule) - - return m - + def execute_makefile(self, path_to_makefile): + if isinstance(path_to_makefile, GnuMakefile): + path = path_to_makefile.makefile_dir + else: + path = path_to_makefile + log.execute('make in %s' % (path,)) + returncode, stdout, stderr = _run_subprocess('/scratchbox/login', ['make', '-C', str(path)]) + self._handle_error(returncode, stdout, stderr, path.join('make')) From fijal at codespeak.net Thu Oct 16 00:15:44 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 00:15:44 +0200 (CEST) Subject: [pypy-svn] r59123 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081015221544.415B616A271@codespeak.net> Author: fijal Date: Thu Oct 16 00:15:43 2008 New Revision: 59123 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Log: fix for darwin Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Thu Oct 16 00:15:43 2008 @@ -9,7 +9,9 @@ cflags = ['-O3', '-fomit-frame-pointer'] # -mdynamic-no-pic for standalone - def __init__(self, cc='gcc'): + def __init__(self, cc=None): + if cc is None: + cc = 'gcc' self.cc = cc def _args_for_shared(self, args): From fijal at codespeak.net Thu Oct 16 00:18:26 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 00:18:26 +0200 (CEST) Subject: [pypy-svn] r59124 - pypy/branch/cbuild-refactor/pypy/translator/c/test Message-ID: <20081015221826.9D8BC16A3A9@codespeak.net> Author: fijal Date: Thu Oct 16 00:18:26 2008 New Revision: 59124 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Log: unskip working test Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Thu Oct 16 00:18:26 2008 @@ -238,9 +238,6 @@ config.translation.platform = 'maemo' cls.config = config - def test_separate_files(self): - py.test.skip("Unsupported") - def test_profopt(self): py.test.skip("Unsupported") From fijal at codespeak.net Thu Oct 16 00:57:25 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 00:57:25 +0200 (CEST) Subject: [pypy-svn] r59125 - in pypy/branch/cbuild-refactor/pypy/translator: c c/test platform Message-ID: <20081015225725.46E3216A3C8@codespeak.net> Author: fijal Date: Thu Oct 16 00:57:23 2008 New Revision: 59125 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Log: Fixes for OS/X. test_standalone fails for mysterious reasons on tuatara Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Thu Oct 16 00:57:23 2008 @@ -31,8 +31,28 @@ def __init__(self, compiler): self.compiler = compiler - def first(self): - return self.build('-fprofile-generate') + def first(self, compiler_driver): + platform = compiler_driver.cfiles + if 0 and platform.name == 'darwin2xxx': + # XXX incredible hack for darwin + cfiles = compiler_driver.cfiles + STR = '/*--no-profiling-for-this-file!--*/' + no_prof = [] + prof = [] + for cfile in compiler_driver.cfiles: + if STR in cfile.read(): + no_prof.append(cfile) + else: + prof.append(cfile) + p_eci = compiler_driver.eci.merge( + ExternalCompilationInfo(compile_extra=['-fprofile-generate'], + link_extra=['-fprofile-generate'])) + ofiles = platform._compile_o_files(prof, p_eci) + _, eci = compiler_driver.eci.get_module_files() + ofiles += platform._compile_o_files(no_prof, eci) + return platform._finish_linking(ofiles, p_eci, None, True) + else: + return self.build('-fprofile-generate') def probe(self, exe, args): # 'args' is a single string typically containing spaces @@ -45,8 +65,6 @@ def build(self, option): eci = ExternalCompilationInfo(compile_extra=[option], link_extra=[option]) - # XXX - #compiler.fix_gcc_random_seed = True return self.compiler._build(eci) class CCompilerDriver(object): @@ -74,7 +92,7 @@ profdrv = ProfDriver(self) dolog = getattr(log, profdrv.name) dolog(args) - exename = profdrv.first() + exename = profdrv.first(self) dolog('Gathering profile data from: %s %s' % ( str(exename), args)) profdrv.probe(exename, args) Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Thu Oct 16 00:57:23 2008 @@ -166,6 +166,29 @@ out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 + def test_profopt_mac_osx_bug(self): + def entry_point(argv): + import os + pid = os.fork() + if pid: + os.waitpid(pid, 0) + else: + os._exit(0) + 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="") + # no counters + t.backendopt() + exe = t.compile() + py.process.cmdexec(exe) + t = Translation(entry_point, backend='c', standalone=True, profopt="", + noprofopt=True) + # no counters + t.backendopt() + exe = t.compile() + py.process.cmdexec(exe) + def test_standalone_large_files(self): from pypy.module.posix.test.test_posix2 import need_sparse_files need_sparse_files() Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Thu Oct 16 00:57:23 2008 @@ -131,19 +131,26 @@ def _args_for_shared(self, args): return ['-shared'] + args - def compile(self, cfiles, eci, outputfilename=None, standalone=True): + def _compile_o_files(self, cfiles, eci): cfiles = [py.path.local(f) for f in cfiles] cfiles += [py.path.local(f) for f in eci.separate_module_files] compile_args = self._compile_args_from_eci(eci) + ofiles = [] + for cfile in cfiles: + ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) + return ofiles + + def compile(self, cfiles, eci, outputfilename=None, standalone=True): + ofiles = self._compile_o_files(cfiles, eci) + return self._finish_linking(ofiles, eci, outputfilename, standalone) + + def _finish_linking(self, ofiles, eci, outputfilename, standalone): if outputfilename is None: - outputfilename = cfiles[0].purebasename - exe_name = py.path.local(os.path.join(str(cfiles[0].dirpath()), + outputfilename = ofiles[0].purebasename + exe_name = py.path.local(os.path.join(str(ofiles[0].dirpath()), outputfilename)) if not standalone: exe_name += '.' + self.so_ext - ofiles = [] - for cfile in cfiles: - ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) return self._link(self.cc, ofiles, self._link_args_from_eci(eci), standalone, exe_name) From fijal at codespeak.net Thu Oct 16 00:58:43 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 00:58:43 +0200 (CEST) Subject: [pypy-svn] r59126 - pypy/branch/cbuild-refactor/pypy/translator/c Message-ID: <20081015225843.30CCF16A3D9@codespeak.net> Author: fijal Date: Thu Oct 16 00:58:42 2008 New Revision: 59126 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Log: argh, didn't mean to check that in Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Thu Oct 16 00:58:42 2008 @@ -33,7 +33,7 @@ def first(self, compiler_driver): platform = compiler_driver.cfiles - if 0 and platform.name == 'darwin2xxx': + if platform.name == 'darwin': # XXX incredible hack for darwin cfiles = compiler_driver.cfiles STR = '/*--no-profiling-for-this-file!--*/' From fijal at codespeak.net Thu Oct 16 01:06:46 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 01:06:46 +0200 (CEST) Subject: [pypy-svn] r59127 - in pypy/branch/cbuild-refactor/pypy/translator/c: . test Message-ID: <20081015230646.D1F8116A3DF@codespeak.net> Author: fijal Date: Thu Oct 16 01:06:46 2008 New Revision: 59127 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Log: Fix bug, simplify, seems to work. Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Thu Oct 16 01:06:46 2008 @@ -31,24 +31,24 @@ def __init__(self, compiler): self.compiler = compiler - def first(self, compiler_driver): - platform = compiler_driver.cfiles + def first(self): + platform = self.compiler.platform if platform.name == 'darwin': # XXX incredible hack for darwin - cfiles = compiler_driver.cfiles + cfiles = self.compiler.cfiles STR = '/*--no-profiling-for-this-file!--*/' no_prof = [] prof = [] - for cfile in compiler_driver.cfiles: + for cfile in self.compiler.cfiles: if STR in cfile.read(): no_prof.append(cfile) else: prof.append(cfile) - p_eci = compiler_driver.eci.merge( + p_eci = self.compiler.eci.merge( ExternalCompilationInfo(compile_extra=['-fprofile-generate'], link_extra=['-fprofile-generate'])) ofiles = platform._compile_o_files(prof, p_eci) - _, eci = compiler_driver.eci.get_module_files() + _, eci = self.compiler.eci.get_module_files() ofiles += platform._compile_o_files(no_prof, eci) return platform._finish_linking(ofiles, p_eci, None, True) else: @@ -92,7 +92,7 @@ profdrv = ProfDriver(self) dolog = getattr(log, profdrv.name) dolog(args) - exename = profdrv.first(self) + exename = profdrv.first() dolog('Gathering profile data from: %s %s' % ( str(exename), args)) profdrv.probe(exename, args) Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Thu Oct 16 01:06:46 2008 @@ -181,13 +181,13 @@ # no counters t.backendopt() exe = t.compile() - py.process.cmdexec(exe) + #py.process.cmdexec(exe) t = Translation(entry_point, backend='c', standalone=True, profopt="", noprofopt=True) # no counters t.backendopt() exe = t.compile() - py.process.cmdexec(exe) + #py.process.cmdexec(exe) def test_standalone_large_files(self): from pypy.module.posix.test.test_posix2 import need_sparse_files From fijal at codespeak.net Thu Oct 16 11:42:21 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 11:42:21 +0200 (CEST) Subject: [pypy-svn] r59128 - pypy/build/bot2/pypybuildbot Message-ID: <20081016094221.3321116A264@codespeak.net> Author: fijal Date: Thu Oct 16 11:42:19 2008 New Revision: 59128 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: increase default timeout for builders (test) Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Thu Oct 16 11:42:19 2008 @@ -46,6 +46,7 @@ *a, **kw): kw['translationArgs'] = translationArgs kw['targetArgs'] = targetArgs + kw['timeout'] = 3600 shell.ShellCommand.__init__(self, workdir, *a, **kw) self.command = (self.command + translationArgs + [self.translationTarget] + targetArgs) From fijal at codespeak.net Thu Oct 16 11:48:06 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 11:48:06 +0200 (CEST) Subject: [pypy-svn] r59129 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081016094806.891EF16A127@codespeak.net> Author: fijal Date: Thu Oct 16 11:48:05 2008 New Revision: 59129 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Log: fix for python2.4 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Thu Oct 16 11:48:05 2008 @@ -30,6 +30,9 @@ self.out = out self.err = err + def __repr__(self): + return "" + class ExecutionResult(object): def __init__(self, returncode, out, err): self.returncode = returncode From fijal at codespeak.net Thu Oct 16 11:48:40 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 11:48:40 +0200 (CEST) Subject: [pypy-svn] r59130 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081016094840.8979716A146@codespeak.net> Author: fijal Date: Thu Oct 16 11:48:40 2008 New Revision: 59130 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Log: real fix for python2.4 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Thu Oct 16 11:48:40 2008 @@ -33,6 +33,8 @@ def __repr__(self): return "" + __str__ = __repr__ + class ExecutionResult(object): def __init__(self, returncode, out, err): self.returncode = returncode From fijal at codespeak.net Thu Oct 16 11:51:13 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 11:51:13 +0200 (CEST) Subject: [pypy-svn] r59131 - pypy/branch/cbuild-refactor/pypy/translator/test Message-ID: <20081016095113.9D1E016A146@codespeak.net> Author: fijal Date: Thu Oct 16 11:51:12 2008 New Revision: 59131 Modified: pypy/branch/cbuild-refactor/pypy/translator/test/test_geninterp.py Log: fix import Modified: pypy/branch/cbuild-refactor/pypy/translator/test/test_geninterp.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/test/test_geninterp.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/test/test_geninterp.py Thu Oct 16 11:51:12 2008 @@ -27,7 +27,6 @@ import py from pypy.tool.udir import udir from pypy.objspace.flow.model import * -from pypy.translator.tool.cbuild import make_module_from_c from pypy.translator.geninterplevel import translate_as_module from pypy.translator.test import snippet from pypy.interpreter.error import OperationError From fijal at codespeak.net Thu Oct 16 12:02:54 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 12:02:54 +0200 (CEST) Subject: [pypy-svn] r59132 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081016100254.B593F16A139@codespeak.net> Author: fijal Date: Thu Oct 16 12:02:54 2008 New Revision: 59132 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py Log: wuaa. don't check in name errors Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py Thu Oct 16 12:02:54 2008 @@ -11,6 +11,11 @@ CFLAGS = ['-O3'] +if os.name != 'nt': + so_ext = '.so' +else: + so_ext = '.dll' + class DistutilsPlatform(Platform): """ This is a generic distutils platform. I hope it'll go away at some point soon completely From fijal at codespeak.net Thu Oct 16 12:04:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 12:04:33 +0200 (CEST) Subject: [pypy-svn] r59133 - pypy/build/bot2 Message-ID: <20081016100433.0AC3516A14A@codespeak.net> Author: fijal Date: Thu Oct 16 12:04:33 2008 New Revision: 59133 Modified: pypy/build/bot2/TODO Log: observation Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Thu Oct 16 12:04:33 2008 @@ -18,3 +18,4 @@ - convention for naming and coalescing alternative builders for the same build +- svnwcrevert is followed by full svn co, this makes little sense, investigate \ No newline at end of file From fijal at codespeak.net Thu Oct 16 12:19:31 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 12:19:31 +0200 (CEST) Subject: [pypy-svn] r59134 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081016101931.D30BC16A14C@codespeak.net> Author: fijal Date: Thu Oct 16 12:19:31 2008 New Revision: 59134 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py Log: we don't need to put . there Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py Thu Oct 16 12:19:31 2008 @@ -12,9 +12,9 @@ CFLAGS = ['-O3'] if os.name != 'nt': - so_ext = '.so' + so_ext = 'so' else: - so_ext = '.dll' + so_ext = 'dll' class DistutilsPlatform(Platform): """ This is a generic distutils platform. I hope it'll go away at some @@ -156,3 +156,9 @@ extra_preargs=self.link_extra, library_dirs=self.eci.library_dirs) + def include_dirs_for_libffi(self): + return ['/usr/include/libffi'] + + def library_dirs_for_libffi(self): + return ['/usr/lib/libffi'] + From fijal at codespeak.net Thu Oct 16 12:35:15 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 12:35:15 +0200 (CEST) Subject: [pypy-svn] r59135 - pypy/dist/pypy/doc Message-ID: <20081016103515.BFF0F169F5F@codespeak.net> Author: fijal Date: Thu Oct 16 12:35:12 2008 New Revision: 59135 Modified: pypy/dist/pypy/doc/maemo.txt Log: an XXX and start a debian paragraph Modified: pypy/dist/pypy/doc/maemo.txt ============================================================================== --- pypy/dist/pypy/doc/maemo.txt (original) +++ pypy/dist/pypy/doc/maemo.txt Thu Oct 16 12:35:12 2008 @@ -113,6 +113,8 @@ and copy the binary result to the N810/Maemo device. You can also login to the virtual environment and execute the ARM binary there. +XXX [fijal] remember to update that it uses inside gcc these days + PyPy's translation tool chain tries to use this cross-compiler when you specify ``--platform=maemo`` to the translate.py script. @@ -174,6 +176,9 @@ 1. On ubuntu linux edit /etc/sysctl.conf to contain:: + XXX [fijal] since it might freeze your machine, I suggest to add a + non-permanent way of doing it (echo 0 > /proc/sys/vm/vdso_enabled) + XXX [fijal] on my machine vdso_enbled = 0 freezed machine and made in unbootable without editing file first. It seems not to be needed though. @@ -232,3 +237,10 @@ .. _`installation instructions`: http://www.scratchbox.org/documentation/user/scratchbox-1.0/html/installdoc.html .. _`scratchbox`: http://scratchbox.org + +debian +++++++ + +in theory we don't need to install debian under scratchbox. in practice though, +if we want to run pypy-c with allworkingmodules we need to a way to install +correct libraries and include files. From arigo at codespeak.net Thu Oct 16 12:45:56 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 16 Oct 2008 12:45:56 +0200 (CEST) Subject: [pypy-svn] r59136 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20081016104556.88F3C16A16C@codespeak.net> Author: arigo Date: Thu Oct 16 12:45:55 2008 New Revision: 59136 Modified: pypy/dist/pypy/translator/backendopt/mallocv.py pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Log: Test and fix to avoid making several identical specializations of the same graph. Modified: pypy/dist/pypy/translator/backendopt/mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/mallocv.py Thu Oct 16 12:45:55 2008 @@ -87,6 +87,9 @@ def copy(self, memo, flagreadonly): return RuntimeSpecNode(self.name, self.TYPE) + def bind_rt_nodes(self, memo, newnodes_iter): + return newnodes_iter.next() + class VirtualSpecNode(SpecNode): @@ -122,6 +125,15 @@ newnode.fields.append(subnode.copy(memo, flagreadonly)) return newnode + def bind_rt_nodes(self, memo, newnodes_iter): + if self in memo: + return memo[self] + newnode = VirtualSpecNode(self.typedesc, [], self.readonly) + memo[self] = newnode + for subnode in self.fields: + newnode.fields.append(subnode.bind_rt_nodes(memo, newnodes_iter)) + return newnode + class VirtualFrame(object): @@ -211,6 +223,17 @@ return False return True +def bind_rt_nodes(srcnodelist, newnodes_list): + """Return srcnodelist with all RuntimeNodes replaced by nodes + coming from newnodes_list. + """ + memo = {} + newnodes_iter = iter(newnodes_list) + result = [node.bind_rt_nodes(memo, newnodes_iter) for node in srcnodelist] + rest = list(newnodes_iter) + assert rest == [], "too many nodes in newnodes_list" + return result + class CannotVirtualize(Exception): pass @@ -221,6 +244,8 @@ class CannotRemoveThisType(Exception): pass +# ____________________________________________________________ + class MallocVirtualizer(object): @@ -230,6 +255,7 @@ self.excdata = rtyper.getexceptiondata() self.graphbuilders = {} self.specialized_graphs = {} + self.specgraphorigin = {} self.inline_and_remove = {} # {graph: op_to_remove} self.inline_and_remove_seen = {} # set of (graph, op_to_remove) self.malloctypedescs = {} @@ -348,6 +374,10 @@ assert len(graph.getargs()) == len(nodelist) if is_trivial_nodelist(nodelist): return 'trivial', graph + if graph in self.specgraphorigin: + orggraph, orgnodelist = self.specgraphorigin[graph] + nodelist = bind_rt_nodes(orgnodelist, nodelist) + graph = orggraph virtualframe = VirtualFrame(graph.startblock, 0, nodelist) key = virtualframe.getfrozenkey() try: @@ -378,6 +408,7 @@ self.specialized_graphs[key] = ('fail', None) else: self.graphbuilders[specgraph] = graphbuilder + self.specgraphorigin[specgraph] = graph, nodelist self.graphs.append(specgraph) Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocv.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_mallocv.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_mallocv.py Thu Oct 16 12:45:55 2008 @@ -53,6 +53,7 @@ graph = graphof(t, fn) if option.view: t.view() + self.original_graph_count = len(t.graphs) # to detect missing keepalives and broken intermediate graphs, # we do the loop ourselves instead of calling remove_simple_mallocs() maxiter = 100 @@ -527,6 +528,30 @@ assert annotator.binding(graph.getargs()[0]).knowntype is int assert annotator.binding(graph.getreturnvar()).knowntype is int + def test_double_spec_order(self): + class A: + pass + def g(a1, a2): + return a1.x - a2.y + # + def fn17(): + a1 = A(); a2 = A() + a1.x = 5; a1.y = 6; a2.x = 7; a2.y = 8 + n1 = g(a1, a2) + # + a1 = A(); a2 = A() + a1.x = 50; a1.y = 60; a2.x = 70; a2.y = 80 + n2 = g(a2, a1) + # + return n1 * n2 + # + assert fn17() == -30 + self.check(fn17, [], [], -30, expected_calls=2) + extra_graphs = len(self.translator.graphs) - self.original_graph_count + assert extra_graphs <= 3 # g(Virtual, Runtime) + # g(Runtime, Virtual) + # g(Virtual, Virtual) + class TestLLTypeMallocRemoval(BaseMallocRemovalTest): type_system = 'lltype' @@ -604,7 +629,7 @@ expected_calls=1) def test_direct_fieldptr(self): - py.test.skip("redo me") + py.test.skip("llptr support not really useful any more") S = lltype.GcStruct('S', ('x', lltype.Signed)) def fn(): @@ -616,7 +641,7 @@ self.check(fn, [], [], 11) def test_direct_fieldptr_2(self): - py.test.skip("redo me") + py.test.skip("llptr support not really useful any more") T = lltype.GcStruct('T', ('z', lltype.Signed)) S = lltype.GcStruct('S', ('t', T), ('x', lltype.Signed), @@ -634,8 +659,7 @@ self.check(fn, [], [], 42) def test_getarraysubstruct(self): - py.test.skip("redo me") - py.test.skip("fails because of the interior structure changes") + py.test.skip("llptr support not really useful any more") U = lltype.Struct('U', ('n', lltype.Signed)) for length in [1, 2]: S = lltype.GcStruct('S', ('a', lltype.FixedSizeArray(U, length))) @@ -724,7 +748,7 @@ self.check(fn, [], [], True, expected_mallocs=0) def test_substruct_not_accessed(self): - py.test.skip("redo me") + py.test.skip("llptr support not really useful any more") SMALL = lltype.Struct('SMALL', ('x', lltype.Signed)) BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL)) def fn(): @@ -735,8 +759,7 @@ self.check(fn, [], [], 12) def test_union(self): - py.test.skip("redo me") - py.test.skip("fails because of the interior structure changes") + py.test.skip("llptr support not really useful any more") UNION = lltype.Struct('UNION', ('a', lltype.Signed), ('b', lltype.Signed), hints = {'union': True}) BIG = lltype.GcStruct('BIG', ('u1', UNION), ('u2', UNION)) @@ -792,7 +815,7 @@ graph = self.check(f, [int], [42], 2 * 42) def test_interior_ptr(self): - py.test.skip("redo me") + py.test.skip("llptr support not really useful any more") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('s', S)) def f(x): @@ -802,7 +825,7 @@ graph = self.check(f, [int], [42], 42) def test_interior_ptr_with_index(self): - py.test.skip("redo me") + py.test.skip("llptr support not really useful any more") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcArray(S) def f(x): @@ -812,7 +835,7 @@ graph = self.check(f, [int], [42], 42) def test_interior_ptr_with_field_and_index(self): - py.test.skip("redo me") + py.test.skip("llptr support not really useful any more") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(x): @@ -822,7 +845,7 @@ graph = self.check(f, [int], [42], 42) def test_interior_ptr_with_index_and_field(self): - py.test.skip("redo me") + py.test.skip("llptr support not really useful any more") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.Struct("T", ('s', S)) U = lltype.GcArray(T) From fijal at codespeak.net Thu Oct 16 13:27:31 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 13:27:31 +0200 (CEST) Subject: [pypy-svn] r59137 - pypy/dist/pypy/doc Message-ID: <20081016112731.4244916A13D@codespeak.net> Author: fijal Date: Thu Oct 16 13:27:27 2008 New Revision: 59137 Modified: pypy/dist/pypy/doc/maemo.txt Log: add debian notes Modified: pypy/dist/pypy/doc/maemo.txt ============================================================================== --- pypy/dist/pypy/doc/maemo.txt (original) +++ pypy/dist/pypy/doc/maemo.txt Thu Oct 16 13:27:27 2008 @@ -243,4 +243,29 @@ in theory we don't need to install debian under scratchbox. in practice though, if we want to run pypy-c with allworkingmodules we need to a way to install -correct libraries and include files. +correct libraries and include files. For example we should use etch and not +lenny, since libffi is in correct version there (4 vs 5). On the other +hand I had no luck installing python on etch.. + +To be able to run debian correctly you need to: + +1. Manually edit /scratchbox/devkits/debian-etch/etc/environment + to add ARCH=arm (instead of ARCH=...), + otherwise apt-get did not work. + +2. Go inside scratchbox and make /etc/apt/sources.list to contain: + + deb ftp://ftp.fi.debian.org/debian/ lenny main contrib non-free + deb-src ftp://ftp.fi.debian.org/debian/ lenny main contrib non-free + +3. Run apt-get update && fakeroot apt-get install libc6 && fakeroot apt-get install python2.5-dev + +5. In order to have pypy-c with all working modules you also need following + packages: + + * libffi-dev + + * zlib1g-dev + + * libbz2-dev + From antocuni at codespeak.net Thu Oct 16 13:35:09 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 16 Oct 2008 13:35:09 +0200 (CEST) Subject: [pypy-svn] r59138 - in pypy/branch/oo-jit/pypy/jit/codegen/cli: . test Message-ID: <20081016113509.B48F416A155@codespeak.net> Author: antocuni Date: Thu Oct 16 13:35:09 2008 New Revision: 59138 Added: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py (contents, props changed) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py Log: refactor ArgsManager to make it testable without involving any CLI opereration, and write actual tests for it; one of those fails Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py Thu Oct 16 13:35:09 2008 @@ -10,11 +10,7 @@ array[i] = types[i] return array -def MakeGenericType(clitype, paramtypes): - array = new_type_array(paramtypes) - return clitype.MakeGenericType(array) - -class ArgsManager: +class BaseArgsManager: def __init__(self): self.type_counter = {} @@ -22,21 +18,19 @@ self.clitype = None self._init_types() - def _load_pypylib(self): - from pypy.translator.cli.query import pypylib, pypylib2 - assembly = None - for name in [pypylib, pypylib2]: - assembly = Assembly.LoadWithPartialName(name) - if assembly: - break - assert assembly is not None - return assembly - def _init_types(self): - pypylib = self._load_pypylib() - self.clitype_InputArgs = pypylib.GetType('pypy.runtime.InputArgs`1') - self.clitype_Void = pypylib.GetType('pypy.runtime.Void') - self.clitype_Pair = pypylib.GetType('pypy.runtime.Pair`2') + self.clitype_InputArgs = None + self.clitype_Void = None + self.clitype_Pair = None + + def _make_generic_type(self, clitype, paramtypes): + raise NotImplementedError + + def _store_by_index(self, meth, gv_arg, i): + raise NotImplementedError + + def _load_by_index(self, meth, i): + raise NotImplementedError def is_open(self): return self.clitype is None @@ -70,43 +64,17 @@ for clitype, count in self.type_counter.iteritems(): self.type_index[clitype] = len(fieldtypes) fieldtypes += [clitype] * count - pairtype = self.clitype_Void + # iterate over reversed(fieldtypes) i = len(fieldtypes)-1 while True: if i < 0: break fieldtype = fieldtypes[i] - pairtype = MakeGenericType(self.clitype_Pair, [fieldtype, pairtype]) + pairtype = self._make_generic_type(self.clitype_Pair, [fieldtype, pairtype]) i-=1 - -## for fieldtype in fieldtypes[::-1]: -## pairtype = MakeGenericType(self.clitype_Pair, [fieldtype, pairtype]) - self.clitype = MakeGenericType(self.clitype_InputArgs, [pairtype]) - - def _store_by_index(self, meth, gv_arg, i): - head_info = self._load_nth_head(meth, i) - gv_arg.load(meth) - meth.il.Emit(OpCodes.Stfld, head_info) - - def _load_by_index(self, meth, i): - head_info = self._load_nth_head(meth, i) - meth.il.Emit(OpCodes.Ldfld, head_info) - - def _load_nth_head(self, meth, n): - il = meth.il - fields_info = self.clitype.GetField("fields") - meth.gv_inputargs.load(meth) - il.Emit(OpCodes.Ldflda, fields_info) - - lastfield_info = fields_info - for _ in range(n): - fieldtype = lastfield_info.get_FieldType() - lastfield_info = fieldtype.GetField("tail") - il.Emit(OpCodes.Ldflda, lastfield_info) - fieldtype = lastfield_info.get_FieldType() - return fieldtype.GetField("head") + self.clitype = self._make_generic_type(self.clitype_InputArgs, [pairtype]) def copy_to_inputargs(self, meth, args_gv): "copy args_gv into the appropriate fields of inputargs" @@ -143,3 +111,49 @@ curidx += 1 indexes.append(curidx) return indexes + + +class ArgsManager(BaseArgsManager): + + def _load_pypylib(self): + from pypy.translator.cli.query import pypylib, pypylib2 + assembly = None + for name in [pypylib, pypylib2]: + assembly = Assembly.LoadWithPartialName(name) + if assembly: + break + assert assembly is not None + return assembly + + def _init_types(self): + pypylib = self._load_pypylib() + self.clitype_InputArgs = pypylib.GetType('pypy.runtime.InputArgs`1') + self.clitype_Void = pypylib.GetType('pypy.runtime.Void') + self.clitype_Pair = pypylib.GetType('pypy.runtime.Pair`2') + + def _make_generic_type(self, clitype, paramtypes): + array = new_type_array(paramtypes) + return clitype.MakeGenericType(array) + + def _store_by_index(self, meth, gv_arg, i): + head_info = self._load_nth_head(meth, i) + gv_arg.load(meth) + meth.il.Emit(OpCodes.Stfld, head_info) + + def _load_by_index(self, meth, i): + head_info = self._load_nth_head(meth, i) + meth.il.Emit(OpCodes.Ldfld, head_info) + + def _load_nth_head(self, meth, n): + il = meth.il + fields_info = self.clitype.GetField("fields") + meth.gv_inputargs.load(meth) + il.Emit(OpCodes.Ldflda, fields_info) + + lastfield_info = fields_info + for _ in range(n): + fieldtype = lastfield_info.get_FieldType() + lastfield_info = fieldtype.GetField("tail") + il.Emit(OpCodes.Ldflda, lastfield_info) + fieldtype = lastfield_info.get_FieldType() + return fieldtype.GetField("head") Added: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py ============================================================================== --- (empty file) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py Thu Oct 16 13:35:09 2008 @@ -0,0 +1,108 @@ +import py +from pypy.jit.codegen.cli.args_manager import BaseArgsManager + +class MyArgsManager(BaseArgsManager): + + def _init_types(self): + self.clitype_InputArgs = 'InputArgs' + self.clitype_Void = 'Void' + self.clitype_Pair = 'Pair' + + def _make_generic_type(self, clitype, paramtypes): + return clitype, paramtypes + + def _store_by_index(self, meth, gv_arg, i): + meth.operations.append(('store_arg', gv_arg, i)) + + def _load_by_index(self, meth, i): + meth.operations.append(('load_arg', i)) + +class FakeMethod: + + def __init__(self): + self.operations = [] + +class FakeGenVar: + + def __init__(self, clitype): + self.clitype = clitype + + def getCliType(self): + return self.clitype + + def store(self, meth): + meth.operations.append(('store', self)) + + +def test_register_types(): + m = MyArgsManager() + assert m.is_open() + m.register_types(['int', 'float', 'int']) + assert m.type_counter['int'] == 2 + assert m.type_counter['float'] == 1 + + m.register_types(['int', 'int', 'int']) + assert m.type_counter['int'] == 3 + assert m.type_counter['float'] == 1 + +def test_close(): + m = MyArgsManager() + m.register_types(['int', 'float', 'int']) + m.close() + assert not m.is_open() + # XXX: this test depend on dictionary order :-/ + assert m.getCliType() == ( + 'InputArgs', [ + ('Pair', [ + 'int', ('Pair', [ + 'int', ('Pair', [ + 'float', 'Void' + ]) + ]) + ]) + ]) + + assert m.type_index['int'] == 0 + assert m.type_index['float'] == 2 + +def test__get_indexes(): + py.test.skip('fixme') + m = MyArgsManager() + m.register_types(['int', 'float', 'int']) + m.close() + indexes = m._get_indexes(['int', 'float', 'int']) + assert indexes == [0, 1, 2] + +def test_copy_to_inputargs(): + meth = FakeMethod() + gv_x = FakeGenVar('int') + gv_y = FakeGenVar('int') + args_gv = [gv_x, gv_y] + + m = MyArgsManager() + m.register(args_gv) + m.close() + m.copy_to_inputargs(meth, args_gv) + + assert meth.operations == [ + ('store_arg', gv_x, 0), + ('store_arg', gv_y, 1) + ] + +def test_copy_from_inputargs(): + meth = FakeMethod() + gv_x = FakeGenVar('int') + gv_y = FakeGenVar('int') + args_gv = [gv_x, gv_y] + + m = MyArgsManager() + m.register(args_gv) + m.close() + m.copy_from_inputargs(meth, args_gv) + + assert meth.operations == [ + ('load_arg', 0), + ('store', gv_x), + ('load_arg', 1), + ('store', gv_y) + ] From antocuni at codespeak.net Thu Oct 16 13:53:24 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 16 Oct 2008 13:53:24 +0200 (CEST) Subject: [pypy-svn] r59139 - in pypy/branch/oo-jit/pypy/jit/codegen/cli: . test Message-ID: <20081016115324.1300616A15C@codespeak.net> Author: antocuni Date: Thu Oct 16 13:53:24 2008 New Revision: 59139 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py Log: the logic in _get_indexes was completely broken. Fix. Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py Thu Oct 16 13:53:24 2008 @@ -101,15 +101,12 @@ def _get_indexes(self, fieldtypes): indexes = [] - curtype = None - curidx = -1 + next_idx_by_type = {} for fieldtype in fieldtypes: - if fieldtype != curtype: - curidx = self.type_index[fieldtype] - curtype = fieldtype - else: - curidx += 1 - indexes.append(curidx) + startidx = self.type_index[fieldtype] + index = next_idx_by_type.get(fieldtype, startidx) + indexes.append(index) + next_idx_by_type[fieldtype] = index+1 return indexes Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py Thu Oct 16 13:53:24 2008 @@ -66,12 +66,11 @@ assert m.type_index['float'] == 2 def test__get_indexes(): - py.test.skip('fixme') m = MyArgsManager() m.register_types(['int', 'float', 'int']) m.close() indexes = m._get_indexes(['int', 'float', 'int']) - assert indexes == [0, 1, 2] + assert indexes == [0, 2, 1] def test_copy_to_inputargs(): meth = FakeMethod() From antocuni at codespeak.net Thu Oct 16 13:57:14 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 16 Oct 2008 13:57:14 +0200 (CEST) Subject: [pypy-svn] r59140 - in pypy/branch/oo-jit/pypy/jit: codegen/cli/test rainbow Message-ID: <20081016115714.AB260168541@codespeak.net> Author: antocuni Date: Thu Oct 16 13:57:14 2008 New Revision: 59140 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py Log: yup, after the fix in args_manager this test passes :-) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Thu Oct 16 13:57:14 2008 @@ -94,8 +94,5 @@ def test_red_int_add_ovf(self): py.test.skip("TODO: exceptions") - def test_learn_nonzeroness(self): - py.test.skip("something wrong with promotion") - def test_degenerated_at_return(self): py.test.skip('test framework does not support getattr on returned instances') Modified: pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py Thu Oct 16 13:57:14 2008 @@ -315,6 +315,7 @@ def bytecode_loop(self): while 1: + #print 'pc = (%s) \t (%s)' % (self.frame.pc, self.frame.bytecode.name) bytecode = self.load_int() assert bytecode >= 0 result = self.opcode_implementations[bytecode](self) From antocuni at codespeak.net Thu Oct 16 14:52:32 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 16 Oct 2008 14:52:32 +0200 (CEST) Subject: [pypy-svn] r59141 - pypy/branch/oo-jit/pypy/jit/codegen/cli/test Message-ID: <20081016125232.8124C16A17F@codespeak.net> Author: antocuni Date: Thu Oct 16 14:52:30 2008 New Revision: 59141 Added: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vlist.py (contents, props changed) Log: add more tests Added: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vlist.py ============================================================================== --- (empty file) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vlist.py Thu Oct 16 14:52:30 2008 @@ -0,0 +1,14 @@ +import py +from pypy.jit.rainbow.test.test_vlist import TestOOType as VListTest +from pypy.jit.codegen.cli.test.test_gencli_interpreter import CompiledCliMixin + +class TestVListCli(CompiledCliMixin, VListTest): + + # for the individual tests see + # ====> ../../../rainbow/test/test_vlist.py + + def skip(self): + py.test.skip('in progress') + + test_force_fixed = skip + From antocuni at codespeak.net Thu Oct 16 15:27:30 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 16 Oct 2008 15:27:30 +0200 (CEST) Subject: [pypy-svn] r59142 - in pypy/branch/oo-jit/pypy/annotation: . test Message-ID: <20081016132730.4B06416A15B@codespeak.net> Author: antocuni Date: Thu Oct 16 15:27:28 2008 New Revision: 59142 Modified: pypy/branch/oo-jit/pypy/annotation/binaryop.py pypy/branch/oo-jit/pypy/annotation/test/test_model.py Log: a failing test and the corresponding fix Modified: pypy/branch/oo-jit/pypy/annotation/binaryop.py ============================================================================== --- pypy/branch/oo-jit/pypy/annotation/binaryop.py (original) +++ pypy/branch/oo-jit/pypy/annotation/binaryop.py Thu Oct 16 15:27:28 2008 @@ -951,6 +951,8 @@ common = r2.ootype elif r2.ootype is None: common = r1.ootype + elif r1.ootype == r2.ootype: + common = r1.ootype elif isinstance(r1.ootype, ootype.Instance) and isinstance(r2.ootype, ootype.Instance): common = ootype.commonBaseclass(r1.ootype, r2.ootype) assert common is not None, ('Mixing of incompatible classes %r, %r' Modified: pypy/branch/oo-jit/pypy/annotation/test/test_model.py ============================================================================== --- pypy/branch/oo-jit/pypy/annotation/test/test_model.py (original) +++ pypy/branch/oo-jit/pypy/annotation/test/test_model.py Thu Oct 16 15:27:28 2008 @@ -192,6 +192,14 @@ assert unionof(SomeOOInstance(C1), SomeOOInstance(D)) == SomeOOInstance(ROOT) +def test_ooclass_array_contains(): + A = ootype.Array(ootype.Signed) + cls = ootype.runtimeClass(A) + s1 = SomeOOClass(A) + s2 = SomeOOClass(A) + s2.const=cls + assert s1.contains(s2) + if __name__ == '__main__': for name, value in globals().items(): if name.startswith('test_'): From fijal at codespeak.net Thu Oct 16 16:05:57 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 16:05:57 +0200 (CEST) Subject: [pypy-svn] r59143 - pypy/trunk/pypy/lib Message-ID: <20081016140557.B594916A1C8@codespeak.net> Author: fijal Date: Thu Oct 16 16:05:55 2008 New Revision: 59143 Modified: pypy/trunk/pypy/lib/_locale.py Log: enough stuff to pass test__locale. it's still probably a bit incomplete though Modified: pypy/trunk/pypy/lib/_locale.py ============================================================================== --- pypy/trunk/pypy/lib/_locale.py (original) +++ pypy/trunk/pypy/lib/_locale.py Thu Oct 16 16:05:55 2008 @@ -36,21 +36,33 @@ for key in _CONSTANTS: setattr(LocaleConfigure, key, ConstantInteger(key)) -config = configure(LocaleConfigure) +locale_config = configure(LocaleConfigure) + for key in _CONSTANTS: - globals()[key] = config[key] + globals()[key] = locale_config[key] del LocaleConfigure -del config +del locale_config + +_LANGINFO_CONSTANTS = ( + 'RADIXCHAR', + 'THOUSEP', +) class LanginfoConfigure: _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) nl_item = SimpleType('nl_item') +for key in _LANGINFO_CONSTANTS: + setattr(LanginfoConfigure, key, ConstantInteger(key)) + config = configure(LanginfoConfigure) nl_item = config['nl_item'] +for key in _LANGINFO_CONSTANTS: + globals()[key] = config[key] del LanginfoConfigure del config HAS_LANGINFO = True + # Ubuntu Gusty i386 structure class lconv(Structure): _fields_ = ( @@ -415,7 +427,7 @@ 'setlocale', 'localeconv', 'strxfrm', 'strcoll', 'gettext', 'dgettext', 'dcgettext', 'textdomain', 'bindtextdomain', 'CHAR_MAX', -) + _CONSTANTS +) + _CONSTANTS + _LANGINFO_CONSTANTS if _bind_textdomain_codeset: __all__ += ('bind_textdomain_codeset',) if HAS_LANGINFO: From pedronis at codespeak.net Thu Oct 16 16:12:38 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 16 Oct 2008 16:12:38 +0200 (CEST) Subject: [pypy-svn] r59144 - pypy/build/bot2 Message-ID: <20081016141238.38EE616A13E@codespeak.net> Author: pedronis Date: Thu Oct 16 16:12:37 2008 New Revision: 59144 Modified: pypy/build/bot2/TODO Log: update TODO before I forget Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Thu Oct 16 16:12:37 2008 @@ -18,4 +18,8 @@ - convention for naming and coalescing alternative builders for the same build -- svnwcrevert is followed by full svn co, this makes little sense, investigate \ No newline at end of file +- implement pre-switch logic to avoid the full checkouts when running non default branches + +- timeout issues with the run of our own rests, probably increase timeout and/or explode other dirs + but also adding better debugging info, right now that the problem is there is not evident + From fijal at codespeak.net Thu Oct 16 16:14:57 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 16:14:57 +0200 (CEST) Subject: [pypy-svn] r59145 - pypy/trunk/pypy/lib Message-ID: <20081016141457.0760916A148@codespeak.net> Author: fijal Date: Thu Oct 16 16:14:57 2008 New Revision: 59145 Modified: pypy/trunk/pypy/lib/dbm.py Log: A bit hopeless way to avoid dependencies at least for my system... Modified: pypy/trunk/pypy/lib/dbm.py ============================================================================== --- pypy/trunk/pypy/lib/dbm.py (original) +++ pypy/trunk/pypy/lib/dbm.py Thu Oct 16 16:14:57 2008 @@ -1,6 +1,6 @@ from ctypes import * import ctypes.util -import os +import os, sys _singleton = 'one' @@ -146,9 +146,13 @@ 'delete': 'dbm_delete', } -try: +if sys.platform != 'darwin': libpath = ctypes.util.find_library('db') - if not libpath: raise + if not libpath: + # XXX this is hopeless... + libpath = ctypes.util.find_library('db-4.5') + if not libpath: + raise Exception("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' lib.__db_ndbm_open.argtypes = [c_char_p, c_int, c_int] @@ -158,7 +162,7 @@ lib.__db_ndbm_fetch.restype = datum lib.__db_ndbm_store.restype = c_int funcs = _bdb_funcs -except: +else: lib = CDLL("/usr/lib/libdbm.dylib") # OS X _platform = 'osx' lib.dbm_open.argtypes = [c_char_p, c_int, c_int] From afa at codespeak.net Thu Oct 16 16:19:45 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 16 Oct 2008 16:19:45 +0200 (CEST) Subject: [pypy-svn] r59146 - in pypy/branch/cbuild-refactor/pypy/translator/platform: . test Message-ID: <20081016141945.260BD16A150@codespeak.net> Author: afa Date: Thu Oct 16 16:19:44 2008 New Revision: 59146 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Log: Let most tests pass on Windows in pypy\translator\platform: - Do not add the exception message to the distutils output: the compiler already provided useful messages. - on win32, "echo" is a shell builtin - convert line endings when needed. Calling subprocess.Popen with universal_newlines=True could have been better, but it does not work with my python 2.5.1 :-( Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Thu Oct 16 16:19:44 2008 @@ -27,8 +27,8 @@ class CompilationError(Exception): def __init__(self, out, err): - self.out = out - self.err = err + self.out = out.replace('\r\n', '\n') + self.err = err.replace('\r\n', '\n') def __repr__(self): return "" @@ -38,8 +38,8 @@ class ExecutionResult(object): def __init__(self, returncode, out, err): self.returncode = returncode - self.out = out - self.err = err + self.out = out.replace('\r\n', '\n') + self.err = err.replace('\r\n', '\n') def __repr__(self): return "" % (self.returncode,) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py Thu Oct 16 16:19:44 2008 @@ -84,8 +84,8 @@ data = '' try: saved_environ = os.environ.copy() + c = stdoutcapture.Capture(mixed_out_err = True) try: - c = stdoutcapture.Capture(mixed_out_err = True) self._build() finally: # workaround for a distutils bugs where some env vars can @@ -96,15 +96,11 @@ foutput, foutput = c.done() data = foutput.read() if data: - fdump = basename.new(ext='errors').open("w") + fdump = basename.new(ext='errors').open("wb") fdump.write(data) fdump.close() except (distutils.errors.CompileError, distutils.errors.LinkError), e: - data = data.rstrip() - if data: - data += '\n' - data += str(e) raise CompilationError('', data) except: print >>sys.stderr, data Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py Thu Oct 16 16:19:44 2008 @@ -58,7 +58,7 @@ executable = self.platform.compile([cfile], ExternalCompilationInfo()) except CompilationError, e: filename = cfile.dirpath().join(cfile.purebasename + '.errors') - assert filename.read() == e.err + assert filename.read('r') == e.err else: py.test.fail("Did not raise") Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py Thu Oct 16 16:19:44 2008 @@ -3,12 +3,19 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.tool.udir import udir from StringIO import StringIO +import sys def test_echo(): res = host.execute('echo', '42 24') assert res.out == '42 24\n' - res = host.execute('echo', ['42', '24']) - assert res.out == '42 24\n' + + if sys.platform == 'win32': + # echo is a shell builtin on Windows + res = host.execute('cmd', ['/c', 'echo', '42', '24']) + assert res.out == '42 24\n' + else: + res = host.execute('echo', ['42', '24']) + assert res.out == '42 24\n' class TestMakefile(object): platform = host From fijal at codespeak.net Thu Oct 16 16:22:50 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 16:22:50 +0200 (CEST) Subject: [pypy-svn] r59147 - pypy/trunk/pypy/lib Message-ID: <20081016142250.A7D4216A17B@codespeak.net> Author: fijal Date: Thu Oct 16 16:22:45 2008 New Revision: 59147 Modified: pypy/trunk/pypy/lib/dbm.py Log: this-never-ever-worked Modified: pypy/trunk/pypy/lib/dbm.py ============================================================================== --- pypy/trunk/pypy/lib/dbm.py (original) +++ pypy/trunk/pypy/lib/dbm.py Thu Oct 16 16:22:45 2008 @@ -59,6 +59,7 @@ value = self.get(key) if value is None: raise KeyError + return value def _set(self, key, value): if not self._aobj: From fijal at codespeak.net Thu Oct 16 16:59:13 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 16:59:13 +0200 (CEST) Subject: [pypy-svn] r59148 - pypy/branch/cbuild-refactor/pypy/module/_minimal_curses Message-ID: <20081016145913.EE22416A17E@codespeak.net> Author: fijal Date: Thu Oct 16 16:59:12 2008 New Revision: 59148 Modified: pypy/branch/cbuild-refactor/pypy/module/_minimal_curses/interp_curses.py Log: this module has changed by a bit... Modified: pypy/branch/cbuild-refactor/pypy/module/_minimal_curses/interp_curses.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/module/_minimal_curses/interp_curses.py (original) +++ pypy/branch/cbuild-refactor/pypy/module/_minimal_curses/interp_curses.py Thu Oct 16 16:59:12 2008 @@ -22,7 +22,7 @@ def convert_error(space, error): msg = error.msg - w_module = space.getbuiltinmodule('_curses') + w_module = space.getbuiltinmodule('_minimal_curses') w_exception_class = space.getattr(w_module, space.wrap('error')) w_exception = space.call_function(w_exception_class, space.wrap(msg)) return OperationError(w_exception_class, w_exception) From afa at codespeak.net Thu Oct 16 18:03:22 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 16 Oct 2008 18:03:22 +0200 (CEST) Subject: [pypy-svn] r59149 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081016160322.8E83816A145@codespeak.net> Author: afa Date: Thu Oct 16 18:03:19 2008 New Revision: 59149 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: Rewrite the Windows build system, to not use the Distutils platform anymore. Now it inherits from linux.Linux, which *may* be the signal that code should be moved to a base class. Some tests pass in test_standalone.py Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Thu Oct 16 18:03:19 2008 @@ -98,6 +98,7 @@ link_flags = ['-pthread'] cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] so_ext = 'so' + exe_ext = '' def __init__(self, cc=None): if cc is None: @@ -149,7 +150,9 @@ outputfilename = ofiles[0].purebasename exe_name = py.path.local(os.path.join(str(ofiles[0].dirpath()), outputfilename)) - if not standalone: + if standalone: + exe_name += '.' + self.exe_ext + else: exe_name += '.' + self.so_ext return self._link(self.cc, ofiles, self._link_args_from_eci(eci), standalone, exe_name) @@ -194,7 +197,7 @@ pypypath = py.path.local(autopath.pypydir) if exe_name is None: - exe_name = cfiles[0].new(ext='') + exe_name = cfiles[0].new(ext=self.exe_ext) m = GnuMakefile(path) m.exe_name = exe_name Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Thu Oct 16 18:03:19 2008 @@ -1,7 +1,125 @@ -from pypy.translator.platform.distutils_platform import DistutilsPlatform +import py, os +from pypy.translator.platform import linux # xxx +from pypy.translator.platform import CompilationError, ExecutionResult +from pypy.translator.platform import log, _run_subprocess +from pypy.tool import autopath -class Windows(DistutilsPlatform): +class Windows(linux.Linux): # xxx name = "win32" so_ext = 'dll' + exe_ext = 'exe' + cc = 'cl.exe' + link = 'link.exe' + + cflags = ['/MDd', '/Z7'] + link_flags = ['/debug'] + + def __init__(self, cc=None): + self.cc = 'cl.exe' + + def _compile_c_file(self, cc, cfile, compile_args): + oname = cfile.new(ext='obj') + args = ['/nologo', '/c'] + compile_args + [str(cfile), '/Fo%s' % (oname,)] + self._execute_c_compiler(cc, args, oname) + return oname + + def _link(self, cc, ofiles, link_args, standalone, exe_name): + args = ['/nologo'] + [str(ofile) for ofile in ofiles] + link_args + args += ['/out:%s' % (exe_name,)] + if not standalone: + args = self._args_for_shared(args) + self._execute_c_compiler(self.link, args, exe_name) + return exe_name + + def _handle_error(self, returncode, stderr, stdout, outname): + if returncode != 0: + # Microsoft compilers write compilation errors to stdout + stderr = stdout + stderr + errorfile = outname.new(ext='errors') + errorfile.write(stderr) + stderrlines = stderr.splitlines() + for line in stderrlines[:5]: + log.ERROR(line) + if len(stderrlines) > 5: + log.ERROR('...') + raise CompilationError(stdout, stderr) + + + def gen_makefile(self, cfiles, eci, exe_name=None, path=None): + cfiles = [py.path.local(f) for f in cfiles] + cfiles += [py.path.local(f) for f in eci.separate_module_files] + + if path is None: + path = cfiles[0].dirpath() + + pypypath = py.path.local(autopath.pypydir) + + if exe_name is None: + exe_name = cfiles[0].new(ext=self.exe_ext) + + m = NMakefile(path) + m.exe_name = exe_name + m.eci = eci + + def pypyrel(fpath): + rel = py.path.local(fpath).relto(pypypath) + if rel: + return os.path.join('$(PYPYDIR)', rel) + else: + return fpath + + rel_cfiles = [m.pathrel(cfile) for cfile in cfiles] + rel_ofiles = [rel_cfile[:-2]+'.obj' for rel_cfile in rel_cfiles] + m.cfiles = rel_cfiles + + rel_includedirs = [pypyrel(incldir) for incldir in + self._preprocess_dirs(eci.include_dirs)] + + m.comment('automatically generated makefile') + definitions = [ + ('PYPYDIR', autopath.pypydir), + ('TARGET', exe_name.basename), + ('DEFAULT_TARGET', '$(TARGET)'), + ('SOURCES', rel_cfiles), + ('OBJECTS', rel_ofiles), + ('LIBS', self._libs(eci.libraries)), + ('LIBDIRS', self._libdirs(eci.library_dirs)), + ('INCLUDEDIRS', self._includedirs(rel_includedirs)), + ('CFLAGS', self.cflags + list(eci.compile_extra)), + ('LDFLAGS', self.link_flags + list(eci.link_extra)), + ('CC', self.cc) + ] + for args in definitions: + m.definition(*args) + + rules = [ + ('all', '$(DEFAULT_TARGET)', []), + ('$(TARGET)', '$(OBJECTS)', '$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS)'), + ('%.obj', '%.c', '$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)'), + ] + + for rule in rules: + m.rule(*rule) + + return m + + def execute_makefile(self, path_to_makefile): + if isinstance(path_to_makefile, NMakefile): + path = path_to_makefile.makefile_dir + else: + path = path_to_makefile + log.execute('make in %s' % (path,)) + oldcwd = path.chdir() + try: + returncode, stdout, stderr = _run_subprocess( + 'nmake', + ['/f', str(path.join('Makefile'))]) + finally: + oldcwd.chdir() + + self._handle_error(returncode, stdout, stderr, path.join('make')) + +class NMakefile(linux.GnuMakefile): + pass # for the moment From fijal at codespeak.net Thu Oct 16 18:10:45 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 18:10:45 +0200 (CEST) Subject: [pypy-svn] r59150 - pypy/branch/cbuild-refactor/pypy/lib Message-ID: <20081016161045.03DA516A0F5@codespeak.net> Author: fijal Date: Thu Oct 16 18:10:45 2008 New Revision: 59150 Modified: pypy/branch/cbuild-refactor/pypy/lib/_pypy_interact.py Log: fix when setupterm fails Modified: pypy/branch/cbuild-refactor/pypy/lib/_pypy_interact.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/lib/_pypy_interact.py (original) +++ pypy/branch/cbuild-refactor/pypy/lib/_pypy_interact.py Thu Oct 16 18:10:45 2008 @@ -17,10 +17,14 @@ pass try: from pyrepl.simple_interact import run_multiline_interactive_console + from pyrepl.curses._curses import error except ImportError: run_simple_interactive_console(mainmodule) else: - run_multiline_interactive_console(mainmodule) + try: + run_multiline_interactive_console(mainmodule) + except error: + run_simple_interactive_console(mainmodule) def run_simple_interactive_console(mainmodule): import code From fijal at codespeak.net Thu Oct 16 18:19:37 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 18:19:37 +0200 (CEST) Subject: [pypy-svn] r59151 - pypy/branch/cbuild-refactor/pypy/lib Message-ID: <20081016161937.76E3F16A14C@codespeak.net> Author: fijal Date: Thu Oct 16 18:19:36 2008 New Revision: 59151 Modified: pypy/branch/cbuild-refactor/pypy/lib/_pypy_interact.py Log: revert 59149 as it didn't help Modified: pypy/branch/cbuild-refactor/pypy/lib/_pypy_interact.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/lib/_pypy_interact.py (original) +++ pypy/branch/cbuild-refactor/pypy/lib/_pypy_interact.py Thu Oct 16 18:19:36 2008 @@ -17,14 +17,10 @@ pass try: from pyrepl.simple_interact import run_multiline_interactive_console - from pyrepl.curses._curses import error except ImportError: run_simple_interactive_console(mainmodule) else: - try: - run_multiline_interactive_console(mainmodule) - except error: - run_simple_interactive_console(mainmodule) + run_multiline_interactive_console(mainmodule) def run_simple_interactive_console(mainmodule): import code From fijal at codespeak.net Thu Oct 16 21:42:59 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 16 Oct 2008 21:42:59 +0200 (CEST) Subject: [pypy-svn] r59155 - pypy/trunk/pypy/module/_lsprof Message-ID: <20081016194259.3413516A1CA@codespeak.net> Author: fijal Date: Thu Oct 16 21:42:57 2008 New Revision: 59155 Modified: pypy/trunk/pypy/module/_lsprof/interp_lsprof.py Log: ignore builtin events for now, let's not crash with fatal rpython error at least when using cProfile Modified: pypy/trunk/pypy/module/_lsprof/interp_lsprof.py ============================================================================== --- pypy/trunk/pypy/module/_lsprof/interp_lsprof.py (original) +++ pypy/trunk/pypy/module/_lsprof/interp_lsprof.py Thu Oct 16 21:42:57 2008 @@ -159,8 +159,8 @@ elif event == 'return': w_self._enter_return(frame.getcode()) else: - raise NotImplementedError("Call to %s" % event) - # we don't support builtin calls here... + # we don't support builtin calls here, let's ignore them + pass class W_Profiler(Wrappable): def __init__(self, space, w_callable, time_unit, subcalls, builtins): From iko at codespeak.net Thu Oct 16 22:02:58 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Thu, 16 Oct 2008 22:02:58 +0200 (CEST) Subject: [pypy-svn] r59156 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081016200258.38392169FE9@codespeak.net> Author: iko Date: Thu Oct 16 22:02:57 2008 New Revision: 59156 Modified: pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py Log: __len__ optimisation of the list constructor is an implementation detail Modified: pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py Thu Oct 16 22:02:57 2008 @@ -513,6 +513,7 @@ a[::2] = tuple(range(5)) self.assertEqual(a, self.type2test([0, 1, 1, 3, 2, 5, 3, 7, 4, 9])) + @impl_detail def test_constructor_exception_handling(self): # Bug #1242657 class F(object): From iko at codespeak.net Thu Oct 16 22:05:42 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Thu, 16 Oct 2008 22:05:42 +0200 (CEST) Subject: [pypy-svn] r59157 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081016200542.A8888169FE9@codespeak.net> Author: iko Date: Thu Oct 16 22:05:42 2008 New Revision: 59157 Modified: pypy/trunk/pypy/objspace/std/test/test_tupleobject.py pypy/trunk/pypy/objspace/std/tupleobject.py Log: fix tuple * 1 is tuple checked by CPython tests Modified: pypy/trunk/pypy/objspace/std/test/test_tupleobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_tupleobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_tupleobject.py Thu Oct 16 22:05:42 2008 @@ -83,6 +83,9 @@ # commute w_res = self.space.mul(w(n), w_tup) assert self.space.eq_w(w_tup3, w_res) + # check tuple*1 is identity (optimisation tested by CPython tests) + w_res = self.space.mul(w_tup, w(1)) + assert w_res is w_tup def test_getslice(self): w = self.space.wrap @@ -277,6 +280,8 @@ assert () * 10 == () assert (5,) * 3 == (5,5,5) assert (5,2) * 2 == (5,2,5,2) + t = (1,2,3) + assert (t * 1) is t def test_getslice(self): assert (5,2,3)[1:2] == (2,) Modified: pypy/trunk/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/tupleobject.py (original) +++ pypy/trunk/pypy/objspace/std/tupleobject.py Thu Oct 16 22:05:42 2008 @@ -79,7 +79,9 @@ except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement - raise + raise + if times == 1: + return w_tuple items = w_tuple.wrappeditems return W_TupleObject(items * times) From cami at codespeak.net Fri Oct 17 08:47:05 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Fri, 17 Oct 2008 08:47:05 +0200 (CEST) Subject: [pypy-svn] r59164 - pypy/dist/pypy/translator/goal Message-ID: <20081017064705.6B42416A155@codespeak.net> Author: cami Date: Fri Oct 17 08:47:02 2008 New Revision: 59164 Modified: pypy/dist/pypy/translator/goal/targetgbprofiling.py Log: cleanupt profiling target Modified: pypy/dist/pypy/translator/goal/targetgbprofiling.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetgbprofiling.py (original) +++ pypy/dist/pypy/translator/goal/targetgbprofiling.py Fri Oct 17 08:47:02 2008 @@ -15,36 +15,75 @@ typical = False count = 100 if argv is not None and len(argv) >= 1: - typical = argv[1] == "1" if len(argv) >= 2: count = int(argv[2]) - - if typical: - op_codes = TYPICAL_LIST - print "Running Typical Set" + if argv[1] == "0": + run_all(count) + elif argv[1] == "1": + run_typical(count) + elif argv[1] == "2": + run_each(count) + elif argv[1] == "3": + run_all_first_order(count) + elif argv[1] == "4": + run_all_second_order(count) else: - op_codes = FULL_LIST - print "Running Normal Set" - - cpu = ProfilingCPU(Interrupt(), iMemory()) + run_all(count) + return 1 + + +def run_typical(count): + print run(TYPICAL_LIST, count) + +def run_all(count): + print run(FULL_LIST, count) + +def run_each(count): + run_each_first_order(count) + run_each_second_order(count) + +def run_each_first_order(count): + forbidden = [0xCB, 211] + op_codes = [0x00]*2 + for i in range(0xFF): + if i not in forbidden and OP_CODES[i] is not None: + op_codes[0] = i + print i, ":", run(op_codes, count) + +def run_each_second_order(count): + op_codes = [0xCB]*2 + for i in range(0xFF): + op_codes[1] = i + print "0xCB :", i, ":" , run(op_codes, count) + +def run_all_first_order(count): + print run(FIRST_ORDER_LIST, count) +def run_all_second_order(count): + print run(SECOND_ORDER_LIST, count) + + +def run(op_codes, count): + cpu = ProfilingCPU(Interrupt(), iMemory()) start_time = time.time() for i in range(count): cpu.run(op_codes) end_time = time.time() - print end_time - start_time - return 1 - - -def create_all_op_codes(): + return end_time - start_time + + +def create_all_first_order(): list = [] forbidden = [0xCB, 211] for i in range(0xFF): if i not in forbidden and OP_CODES[i] is not None: list.append(i) - - forbidden = [] + return list + +def create_all_second_order(): + list = [] + forbidden = [] for i in range(0xFF): if i not in forbidden: list.append(0xCB) @@ -52,6 +91,7 @@ return list + def create_typical_op_codes(): list = [] append_to_opcode_list(list, 0xff, 911896); @@ -91,7 +131,12 @@ list.append(op_code) TYPICAL_LIST = create_typical_op_codes() -FULL_LIST = create_all_op_codes() + +FIRST_ORDER_LIST = create_all_first_order() +SECOND_ORDER_LIST = create_all_second_order() +FULL_LIST = [] +FULL_LIST.extend(FIRST_ORDER_LIST) +FULL_LIST.extend(SECOND_ORDER_LIST) # _____ Define and setup target ___ From witulski at codespeak.net Fri Oct 17 10:10:35 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Fri, 17 Oct 2008 10:10:35 +0200 (CEST) Subject: [pypy-svn] r59165 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081017081035.AA30716A1F8@codespeak.net> Author: witulski Date: Fri Oct 17 10:10:33 2008 New Revision: 59165 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: Added MOV(Stack, Register) + test to enable Stackreuse Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Fri Oct 17 10:10:33 2008 @@ -50,6 +50,17 @@ rexB, modrm1 = self.get_register_bits(arg1.location.reg) elif isinstance(arg1.location, Register8): modrm1 = self.get_register_bits_8Bit(arg1.location.reg) + # special case: Stack and Register exchanged + elif isinstance(arg1.location, Stack64) and isinstance(arg2.location, Register64): + rexB, modrm1 = self.get_register_bits(arg2.location.reg) + self.write_rex_byte(rexW, rexB, rexX, rexR) + self.write(opcode) + # exchanged mod1,mod2, dont know why :) + self.write_modRM_byte(mod, modrm1, modrm2) + # no scale(has no effect on rsp), no index, base = rsp + self.write_SIB(0, 4, 4) + self.writeImm32(arg1.location.offset) + return quadreg_instr # exchange the two arguments (modrm2/modrm1) if isinstance(arg2,Immediate32): @@ -202,7 +213,8 @@ _MOV_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, None, "\xC7", 3, None, 0) _MOV_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x89", 3, None, None) _MOV_QWREG_IMM64 = make_two_operand_instr_with_alternate_encoding(1,0,0,None,"B8",None,None) - _MOV_QWREG_STACK = make_two_operand_instr( 1, 0, 0, None, "\x8B", 2, None, 4)#4 =RSP + _MOV_QWREG_STACK = make_two_operand_instr( 1, 0, 0, None, "\x8B", 2, None, 4)#4 =RSP + _MOV_STACK_QWREG = make_two_operand_instr( 1, 0, 0, None, "\x89", 2, None, 4) _IDIV_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xF7", 3, None, 7) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Fri Oct 17 10:10:33 2008 @@ -106,6 +106,7 @@ self.known_gv = [] # contains the live genvars (used for spilling and allocation) for reg in used_registers: del self.freeregisters[reg.location.reg] + self.free_stack_pos = {} def _open(self): pass @@ -304,15 +305,14 @@ self._open() gv_return = self.allocate_register("rax") # if there unused genVars on the stack - # pop them away - while not self.stackdepth == 0: - self.mc.POP(gv_return) - self.stackdepth = self.stackdepth -1 + # throw them away + if not self.stackdepth == 0: + self.mc.ADD(IntVar(Register64("rsp")), Immediate32(self.stackdepth*8)) if not gv_returnvar == None:#check void return self.mc.MOV(gv_return, gv_returnvar) self.mc.RET() self._close() - assert self.stackdepth == 0 + #assert self.stackdepth == 0 # FIXME: uses 32bit displ # TODO: return also stackdepth or pop! @@ -439,8 +439,14 @@ if gv_to_spill.location.throw_away: return gv_to_spill else: + #search for free stack position + for i in range(self.stackdepth): + if i in self.free_stack_pos.keys(): + pass + # TODO: move gv_to_spill, stack(i) self.stackdepth = self.stackdepth +1 - self.mc.PUSH(gv_to_spill) + self.mc.PUSH(gv_to_spill) + self.free_stack_pos[self.stackdepth] = None # remember as used new_gv = IntVar(Register64(gv_to_spill.location.reg)) gv_to_spill.location = Stack64(self.stackdepth) return new_gv @@ -451,6 +457,7 @@ gv_new = self.allocate_register(None, dont_alloc) if a_spilled_gv.location.offset == self.stackdepth: self.mc.POP(gv_new) + del self.free_stack_pos[self.stackdepth] self.stackdepth = self.stackdepth -1 assert self.stackdepth >= 0 a_spilled_gv.location = Register64(gv_new.location.reg) @@ -463,8 +470,7 @@ # else access the memory # FIXME: if this genVar becomes the top of stack it will never be pushed self.mc.MOV(gv_new, IntVar(Stack64(8*(self.stackdepth-a_spilled_gv.location.offset))))#8=scale - #print "debug:",self.stackdepth - #print a_spilled_gv.location.offset + del self.free_stack_pos[a_spilled_gv.location.offset] a_spilled_gv.location = Register64(gv_new.location.reg) self.known_gv.remove(gv_new) return a_spilled_gv Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Fri Oct 17 10:10:33 2008 @@ -11,6 +11,22 @@ def skip(self): py.test.skip("not implemented yet") + +# pushes/pos some values and than uses a mem access to access the stack +def make_mem_func2(rgenop): + sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed], lltype.Signed)) + builder, gv_mem_func, [gv_x] = rgenop.newgraph(sigtoken, "mem_op") + builder.start_writing() + builder.genop1("int_push", gv_x) + builder.genop1("int_push", gv_x) + builder.mc.MOV(gv_x, rgenop.genconst(42)) + builder.mc.MOV(IntVar(Stack64(8)), gv_x) + builder.genop1("int_pop", gv_x) + builder.genop1("int_pop", gv_x) + builder.finish_and_return(sigtoken, gv_x) + builder.end() + return gv_mem_func + # pushes/pos some values and than uses a mem access to access the stack def make_mem_func(rgenop): sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)) @@ -509,6 +525,13 @@ result = fnptr(-1,2) assert result == 5 + def test_memory_access2(self): + mem_func = make_mem_func2(self.RGenOp()) + fnptr = self.cast(mem_func,1) + result = fnptr(0) + assert result == 42 + + # def test_invert(self): # inv_function = make_one_op_instr(self.RGenOp(),"int_invert") # fnptr = self.cast(inv_function,1) From iko at codespeak.net Fri Oct 17 10:59:19 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Fri, 17 Oct 2008 10:59:19 +0200 (CEST) Subject: [pypy-svn] r59166 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081017085919.4D9D516A151@codespeak.net> Author: iko Date: Fri Oct 17 10:59:16 2008 New Revision: 59166 Modified: pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py Log: missing module name Modified: pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py Fri Oct 17 10:59:16 2008 @@ -513,7 +513,7 @@ a[::2] = tuple(range(5)) self.assertEqual(a, self.type2test([0, 1, 1, 3, 2, 5, 3, 7, 4, 9])) - @impl_detail + @test_support.impl_detail def test_constructor_exception_handling(self): # Bug #1242657 class F(object): From fijal at codespeak.net Fri Oct 17 11:26:03 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 17 Oct 2008 11:26:03 +0200 (CEST) Subject: [pypy-svn] r59167 - pypy/trunk/lib-python Message-ID: <20081017092603.DDB5016A137@codespeak.net> Author: fijal Date: Fri Oct 17 11:26:03 2008 New Revision: 59167 Modified: pypy/trunk/lib-python/conftest.py Log: skip test_audioop Modified: pypy/trunk/lib-python/conftest.py ============================================================================== --- pypy/trunk/lib-python/conftest.py (original) +++ pypy/trunk/lib-python/conftest.py Fri Oct 17 11:26:03 2008 @@ -126,7 +126,7 @@ RegrTest('test_array.py', core=True, usemodules='struct'), RegrTest('test_asynchat.py', usemodules='thread'), RegrTest('test_atexit.py', core=True), - RegrTest('test_audioop.py'), + RegrTest('test_audioop.py', skip=True), RegrTest('test_augassign.py', core=True), RegrTest('test_base64.py'), RegrTest('test_bastion.py'), From antocuni at codespeak.net Fri Oct 17 13:31:07 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 17 Oct 2008 13:31:07 +0200 (CEST) Subject: [pypy-svn] r59169 - pypy/branch/oo-jit/pypy/jit/codegen/cli/test Message-ID: <20081017113107.75A4C16A1F8@codespeak.net> Author: antocuni Date: Fri Oct 17 13:31:05 2008 New Revision: 59169 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vlist.py Log: skip this test for now Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vlist.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vlist.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vlist.py Fri Oct 17 13:31:05 2008 @@ -10,5 +10,5 @@ def skip(self): py.test.skip('in progress') - test_force_fixed = skip - + def test_force_fixed(self): + py.test.skip("very strange bug, crashes both mono and .NET") From afa at codespeak.net Fri Oct 17 14:14:07 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 17 Oct 2008 14:14:07 +0200 (CEST) Subject: [pypy-svn] r59170 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081017121407.606B516A128@codespeak.net> Author: afa Date: Fri Oct 17 14:14:04 2008 New Revision: 59170 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Log: Try to get some useful information when your test raise a CompilationError. Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Fri Oct 17 14:14:04 2008 @@ -6,6 +6,7 @@ import sys, py, os from pypy.tool.ansi_print import ansi_log +from py.__.code import safe_repr log = py.log.Producer("platform") py.log.setconsumer("platform", ansi_log) @@ -31,7 +32,7 @@ self.err = err.replace('\r\n', '\n') def __repr__(self): - return "" + return "" % safe_repr._repr(self.err) __str__ = __repr__ From antocuni at codespeak.net Fri Oct 17 14:21:21 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 17 Oct 2008 14:21:21 +0200 (CEST) Subject: [pypy-svn] r59171 - pypy/branch/oo-jit/pypy/translator/cli Message-ID: <20081017122121.33F9116A13A@codespeak.net> Author: antocuni Date: Fri Oct 17 14:21:20 2008 New Revision: 59171 Modified: pypy/branch/oo-jit/pypy/translator/cli/rte.py Log: copy pypylib.dll to the dir where the program is executed Modified: pypy/branch/oo-jit/pypy/translator/cli/rte.py ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/rte.py (original) +++ pypy/branch/oo-jit/pypy/translator/cli/rte.py Fri Oct 17 14:21:20 2008 @@ -2,7 +2,6 @@ Support for an automatically compiled Run Time Environment. The source of the RTE is in the src/ directory. """ - import os import os.path import shutil @@ -123,4 +122,6 @@ cache.remove() if __name__ == '__main__': - get_pypy_dll() + import shutil + pypylib = get_pypy_dll() + shutil.copy(pypylib, '.') From antocuni at codespeak.net Fri Oct 17 14:22:32 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 17 Oct 2008 14:22:32 +0200 (CEST) Subject: [pypy-svn] r59172 - in pypy/branch/oo-jit/pypy/jit: codegen/cli/test timeshifter Message-ID: <20081017122232.67FCC16A115@codespeak.net> Author: antocuni Date: Fri Oct 17 14:22:31 2008 New Revision: 59172 Added: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vdict.py (contents, props changed) Modified: pypy/branch/oo-jit/pypy/jit/timeshifter/vdict.py Log: use different hash functions for different ootypes. Add more jit backend tests Added: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vdict.py ============================================================================== --- (empty file) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_vdict.py Fri Oct 17 14:22:31 2008 @@ -0,0 +1,10 @@ +import py +from pypy.jit.rainbow.test.test_vdict import TestOOType as VDictTest +from pypy.jit.codegen.cli.test.test_gencli_interpreter import CompiledCliMixin + +class TestVDictCli(CompiledCliMixin, VDictTest): + + # for the individual tests see + # ====> ../../../rainbow/test/test_vdict.py + + pass Modified: pypy/branch/oo-jit/pypy/jit/timeshifter/vdict.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/timeshifter/vdict.py (original) +++ pypy/branch/oo-jit/pypy/jit/timeshifter/vdict.py Fri Oct 17 14:22:31 2008 @@ -208,7 +208,13 @@ self.tok_ll_set = RGenOp.methToken(DICT, 'll_set') def _get_eq_hash(self, DICT): - return operator.eq, hash + KEY = DICT.KEY + eq = operator.eq + if KEY in (ootype.String, ootype.Unicode): + return eq, ootype.oohash + elif KEY in (ootype.Instance, ootype.Record): + return eq, ootype.ooidentityhash + return eq, hash # work at least for primitive types def gen_newdict(self, builder, args_gv): raise NotImplementedError From afa at codespeak.net Fri Oct 17 14:35:16 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 17 Oct 2008 14:35:16 +0200 (CEST) Subject: [pypy-svn] r59173 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081017123516.2709316A253@codespeak.net> Author: afa Date: Fri Oct 17 14:35:15 2008 New Revision: 59173 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py Log: Give a sensible name to the default DistutilsPlatform object: it is used to select compilation options. The base DistutilsPlatform object now works on Windows. Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py Fri Oct 17 14:35:15 2008 @@ -20,8 +20,12 @@ """ This is a generic distutils platform. I hope it'll go away at some point soon completely """ + name = "distutils" + def __init__(self, cc=None): self.cc = cc + if self.name == "distutils": + self.name = sys.platform def _ensure_correct_math(self): if self.name != 'win32': From antocuni at codespeak.net Fri Oct 17 14:36:39 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 17 Oct 2008 14:36:39 +0200 (CEST) Subject: [pypy-svn] r59174 - pypy/branch/oo-jit/pypy/jit/codegen/cli/test Message-ID: <20081017123639.2C77416A25D@codespeak.net> Author: antocuni Date: Fri Oct 17 14:36:38 2008 New Revision: 59174 Added: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py (contents, props changed) Log: cool, about half of the promotion tests pass out of the box on cli Added: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py ============================================================================== --- (empty file) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py Fri Oct 17 14:36:38 2008 @@ -0,0 +1,23 @@ +import py +from pypy.jit.rainbow.test.test_promotion import TestOOType as PromotionTest +from pypy.jit.codegen.cli.test.test_gencli_interpreter import CompiledCliMixin + +class TestPromotionCli(CompiledCliMixin, PromotionTest): + + # for the individual tests see + # ====> ../../../rainbow/test/test_promotion.py + + def skip(self): + py.test.skip('in progress') + + test_many_promotions = skip + test_two_promotions = skip + more_promotes = skip + mixed_merges = skip + remembers_across_mp = skip + test_virtual_list_copy = skip + test_raise_result_mixup = skip + test_two_promotions_in_call = skip + test_promote_class = skip + test_promote_class_vstruct = skip + test_read___class___after_promotion = skip From afa at codespeak.net Fri Oct 17 15:10:39 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 17 Oct 2008 15:10:39 +0200 (CEST) Subject: [pypy-svn] r59177 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081017131039.E6E5716A14C@codespeak.net> Author: afa Date: Fri Oct 17 15:10:39 2008 New Revision: 59177 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: On Windows, try to find and install the environment needed to run the Microsoft compiler programs. Otherwise, don't do anything and hope that the environment is already set. Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Fri Oct 17 15:10:39 2008 @@ -1,10 +1,52 @@ -import py, os +import py, os, sys from pypy.translator.platform import linux # xxx from pypy.translator.platform import CompilationError, ExecutionResult from pypy.translator.platform import log, _run_subprocess from pypy.tool import autopath +def _get_msvc_tools(): + # The same compiler must be used for the python interpreter + # and extension modules + msc_pos = sys.version.find('MSC v.') + if msc_pos == -1: + # Not a windows platform... + return None + + msc_ver = int(sys.version[msc_pos+6:msc_pos+10]) + # 1300 -> 70, 1310 -> 71, 1400 -> 80, 1500 -> 90 + vsver = (msc_ver / 10) - 60 + return os.environ['VS%sCOMNTOOLS' % vsver] + +def _install_msvc_env(): + + vcvars = os.path.join(_get_msvc_tools(), 'vsvars32.bat') + if not vcvars: + return + + import subprocess + popen = subprocess.Popen('"%s" & set' % (vcvars,), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + stdout, stderr = popen.communicate() + if popen.wait() != 0: + raise IOError(stderr) + for line in stdout.split("\n"): + if '=' not in line: + continue + key, value = line.split('=', 1) + if key.upper() in ['PATH', 'INCLUDE', 'LIB']: + os.environ[key] = value + +try: + _install_msvc_env() +except Exception, e: + print >>sys.stderr, "Could not find a suitable Microsoft Compiler" + import traceback + traceback.print_exc() + # Assume that the compiler is already part of the environment + class Windows(linux.Linux): # xxx name = "win32" so_ext = 'dll' From afa at codespeak.net Fri Oct 17 15:19:28 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 17 Oct 2008 15:19:28 +0200 (CEST) Subject: [pypy-svn] r59181 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081017131928.2B0D316A151@codespeak.net> Author: afa Date: Fri Oct 17 15:19:27 2008 New Revision: 59181 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: Log message about updated environment Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Fri Oct 17 15:19:27 2008 @@ -38,6 +38,7 @@ key, value = line.split('=', 1) if key.upper() in ['PATH', 'INCLUDE', 'LIB']: os.environ[key] = value + log.msg("Updated environment with %s" % (vcvars,)) try: _install_msvc_env() From afa at codespeak.net Fri Oct 17 15:33:29 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 17 Oct 2008 15:33:29 +0200 (CEST) Subject: [pypy-svn] r59187 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081017133329.48DBA16A03E@codespeak.net> Author: afa Date: Fri Oct 17 15:33:28 2008 New Revision: 59187 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: Correct link options for Windows platform. test_cbuild.py passes Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Fri Oct 17 15:33:28 2008 @@ -62,6 +62,19 @@ def __init__(self, cc=None): self.cc = 'cl.exe' + def _libs(self, libraries): + return ['%s' % (lib,) for lib in libraries] + + def _libdirs(self, library_dirs): + return ['/LIBPATH:%s' % (ldir,) for ldir in library_dirs] + + def _args_for_shared(self, args): + return ['/dll'] + args + + def _link_args_from_eci(self, eci): + args = super(Windows, self)._link_args_from_eci(eci) + return args + ['/EXPORT:%s' % symbol for symbol in eci.export_symbols] + def _compile_c_file(self, cc, cfile, compile_args): oname = cfile.new(ext='obj') args = ['/nologo', '/c'] + compile_args + [str(cfile), '/Fo%s' % (oname,)] From afa at codespeak.net Fri Oct 17 15:44:25 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 17 Oct 2008 15:44:25 +0200 (CEST) Subject: [pypy-svn] r59188 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081017134425.52D6416A090@codespeak.net> Author: afa Date: Fri Oct 17 15:44:24 2008 New Revision: 59188 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: Windows compilation platform: - Use debug options only when the interpreter is from a debug build - give an extension to linked libraries Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Fri Oct 17 15:44:24 2008 @@ -56,14 +56,19 @@ cc = 'cl.exe' link = 'link.exe' - cflags = ['/MDd', '/Z7'] - link_flags = ['/debug'] + cflags = ['/MD'] + link_flags = [] def __init__(self, cc=None): self.cc = 'cl.exe' + # Install debug options only when interpreter is in debug mode + if sys.executable.lower().endswith('_d.exe'): + self.cflags = ['/MDd', '/Z7'] + self.link_flags = ['/debug'] + def _libs(self, libraries): - return ['%s' % (lib,) for lib in libraries] + return ['%s.lib' % (lib,) for lib in libraries] def _libdirs(self, library_dirs): return ['/LIBPATH:%s' % (ldir,) for ldir in library_dirs] From afa at codespeak.net Fri Oct 17 17:01:43 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 17 Oct 2008 17:01:43 +0200 (CEST) Subject: [pypy-svn] r59191 - pypy/branch/cbuild-refactor/pypy/translator/c Message-ID: <20081017150143.49E2216A068@codespeak.net> Author: afa Date: Fri Oct 17 17:01:41 2008 New Revision: 59191 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Log: Adaptations of genc.py for Windows platform: - in Makefile, do not generate the profopt targets and definitions. the "$(shell python ...)" syntax is not understood by Microsoft's NMake anyway. - Add python include and library path, to work even when run from a python source tree. Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Fri Oct 17 17:01:41 2008 @@ -118,8 +118,20 @@ from distutils import sysconfig python_inc = sysconfig.get_python_inc() pypy_include_dir = py.path.local(autopath.pypydir).join('translator', 'c') + include_dirs = [python_inc, pypy_include_dir] + library_dirs = [] + + if sys.platform == 'win32': + library_dirs.append(py.path.local(sys.exec_prefix).join('libs')) + + # Append the source distribution include and library directories, + # this allows genc on windows to work in the source tree + include_dirs.append(py.path.local(sys.exec_prefix).join('PC')) + library_dirs.append(py.path.local(sys.executable).dirpath()) + return ExternalCompilationInfo( - include_dirs=[python_inc, pypy_include_dir] + include_dirs=include_dirs, + library_dirs=library_dirs, ) def build_database(self): @@ -430,9 +442,9 @@ cfiles = [self.c_source_filename] + self.extrafiles mk = self.translator.platform.gen_makefile(cfiles, self.eci, path=targetdir) - mk.definition('ABS_TARGET', '$(shell python -c "import sys,os; print os.path.abspath(sys.argv[1])" $(TARGET))') if self.has_profopt(): profopt = self.config.translation.profopt + mk.definition('ABS_TARGET', '$(shell python -c "import sys,os; print os.path.abspath(sys.argv[1])" $(TARGET))') mk.definition('DEFAULT_TARGET', 'profopt') mk.definition('PROFOPT', profopt) @@ -447,12 +459,15 @@ ('llsafer', '', '$(MAKE) CFLAGS="-O2 -DRPY_LL_ASSERT" $(TARGET)'), ('lldebug', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DRPY_LL_ASSERT" $(TARGET)'), ('profile', '', '$(MAKE) CFLAGS="-g -pg $(CFLAGS)" LDFLAGS="-pg $(LDFLAGS)" $(TARGET)'), - ('profopt', '', [ - '$(MAKENOPROF)', - '$(MAKE) CFLAGS="-fprofile-generate $(CFLAGS)" LDFLAGS="-fprofile-generate $(LDFLAGS)" $(TARGET)', - 'cd $(PYPYDIR)/translator/goal && $(ABS_TARGET) $(PROFOPT)', - '$(MAKE) clean_noprof', - '$(MAKE) CFLAGS="-fprofile-use $(CFLAGS)" LDFLAGS="-fprofile-use $(LDFLAGS)" $(TARGET)'])] + ] + if self.has_profopt(): + rules.append( + ('profopt', '', [ + '$(MAKENOPROF)', + '$(MAKE) CFLAGS="-fprofile-generate $(CFLAGS)" LDFLAGS="-fprofile-generate $(LDFLAGS)" $(TARGET)', + 'cd $(PYPYDIR)/translator/goal && $(ABS_TARGET) $(PROFOPT)', + '$(MAKE) clean_noprof', + '$(MAKE) CFLAGS="-fprofile-use $(CFLAGS)" LDFLAGS="-fprofile-use $(LDFLAGS)" $(TARGET)'])) for rule in rules: mk.rule(*rule) From afa at codespeak.net Fri Oct 17 17:34:36 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 17 Oct 2008 17:34:36 +0200 (CEST) Subject: [pypy-svn] r59193 - pypy/branch/cbuild-refactor/pypy/translator/c/src Message-ID: <20081017153436.C932B16A13E@codespeak.net> Author: afa Date: Fri Oct 17 17:34:36 2008 New Revision: 59193 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/src/thread_nt.h Log: Try to correctly declare a thread-local variable on Windows Modified: pypy/branch/cbuild-refactor/pypy/translator/c/src/thread_nt.h ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/src/thread_nt.h (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/src/thread_nt.h Fri Oct 17 17:34:36 2008 @@ -234,6 +234,7 @@ /* Thread-local storage */ #define RPyThreadTLS DWORD +#define __thread __declspec(thread) char *RPyThreadTLS_Create(RPyThreadTLS *result) { From fijal at codespeak.net Fri Oct 17 18:18:26 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 17 Oct 2008 18:18:26 +0200 (CEST) Subject: [pypy-svn] r59194 - pypy/extradoc/talk/pyconpl-2008 Message-ID: <20081017161826.0F4C7169F5B@codespeak.net> Author: fijal Date: Fri Oct 17 18:18:25 2008 New Revision: 59194 Added: pypy/extradoc/talk/pyconpl-2008/talk.txt (contents, props changed) Log: Some slides draft (in polish) Added: pypy/extradoc/talk/pyconpl-2008/talk.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pyconpl-2008/talk.txt Fri Oct 17 18:18:25 2008 @@ -0,0 +1,95 @@ +================================================ +PyPy - nowe podejscie do tworzenia interpreterow +================================================ + +O czym bede opowiadal +===================== + +* Co to jest PyPy? + +* Dlaczego? + +* Co chcemy osiagnac? + +* Jak nam idzie? + +Kim jestem? +=========== + +* Maciej Fijalkowski + +* od ~2 lat zajmuje sie glownie PyPy + +* pracuje dla Merlinux GmbH XXX link + +* nie umiem ustawic polskich liter... + +Co to jest PyPy? +================ + +* interpreter pythona napisany w pythonie + +* framework do pisania interpreterow dynamicznych + jezykow + +* open source software + +* dzis bede mowil glownie o interpreterze + +Po co nam to? +============= + +* CPython jest fajny, ale ciezko zmienic pewne decyzje + (np garbage collector) + +* Napisany w C + +* Srodowisko, ktore umie pythona, a do rozwijania jezyka + potrzebni sa ludzie biegli w C + +* XXX ... + +Status na dzis +============================== + +* 2.5 + +* ctypes (np pysqlite-ctypes, pyglet, pymunk ...) + +* django + +* wiekszosc testow CPython'a + +* sympy + +* twoj program... + + +xxx + +Sandbox +======= + +Maemo +===== + +Cele +==== + +JIT +=== + +Q&A +=== + + +Dlaczego pypy + +Kilka dem + +Co z tego mamy + +Maemo + +Sandbox + From afa at codespeak.net Fri Oct 17 20:05:44 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 17 Oct 2008 20:05:44 +0200 (CEST) Subject: [pypy-svn] r59196 - pypy/branch/cbuild-refactor/pypy/translator/c Message-ID: <20081017180544.A044C16A0D0@codespeak.net> Author: afa Date: Fri Oct 17 20:05:42 2008 New Revision: 59196 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Log: ModuleWithCleanup member functions should keep the module alive, otherwise it get freed and dlclose'd before you call the function. The Wrapper trick does this without creating a cycle, which would defeat the "Cleanup" feature. Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Fri Oct 17 20:05:42 2008 @@ -276,7 +276,18 @@ def __getattr__(self, name): mod = self.__dict__['mod'] - return getattr(mod, name) + obj = getattr(mod, name) + 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): + self.mod = mod + 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'] From cami at codespeak.net Sat Oct 18 12:38:47 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Sat, 18 Oct 2008 12:38:47 +0200 (CEST) Subject: [pypy-svn] r59205 - in pypy/dist/pypy/lang/gameboy: . debug Message-ID: <20081018103847.1592C16A081@codespeak.net> Author: cami Date: Sat Oct 18 12:38:47 2008 New Revision: 59205 Modified: pypy/dist/pypy/lang/gameboy/debug/debug.py pypy/dist/pypy/lang/gameboy/timer.py Log: cleanup up debug file Modified: pypy/dist/pypy/lang/gameboy/debug/debug.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/debug/debug.py (original) +++ pypy/dist/pypy/lang/gameboy/debug/debug.py Sat Oct 18 12:38:47 2008 @@ -89,6 +89,7 @@ CHECKED_OP_CODES = [0x00] CHECKED_FETCH_OP_CODES = [] BAR_WIDTH = 79 +PRINT_OPCODE=True def log(opCode, is_fetch_execute=False): global COUNT, op_codes, fetch_execute_op_codes @@ -132,17 +133,19 @@ def print_results(): global COUNT, op_codes, fetch_execute_op_codes - codes = zip(map(lambda x: "%4s" % hex(x), range(len(op_codes))), op_codes) - - fetch_exec_keys = map(lambda x: "%4s %4s" % (hex(x[0]), hex(x[1])), - zip([0x83]*len(fetch_execute_op_codes), - range(len(fetch_execute_op_codes)))) + print_function = (lambda x: "%4s" % hex(x)) + codes = zip(map( print_function, range(len(op_codes))), op_codes) + print_function = (lambda x: "%4s %4s" % (hex(x[0]), hex(x[1]))) + opcode_range = range(len(fetch_execute_op_codes)) + arguments = zip([0x83] * len(fetch_execute_op_codes), opcode_range) + fetch_exec_keys = map( print_function, opcode_range, arguments ) + # Append the fetchexecuted opcodes to the list codes.extend(zip(fetch_exec_keys, fetch_execute_op_codes)) codes = sorted(codes, key=operator.itemgetter(1)) for code in codes: if code[1] != 0: - print "%8s : %s" % (code[0], code[1]) + print "%8s \t %s" % (code[0], code[1]) \ No newline at end of file Modified: pypy/dist/pypy/lang/gameboy/timer.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/timer.py (original) +++ pypy/dist/pypy/lang/gameboy/timer.py Sat Oct 18 12:38:47 2008 @@ -156,5 +156,5 @@ pass def get_time(self): - return int(time.time()*1000) + return (time.time()*1000) From cami at codespeak.net Sat Oct 18 12:39:48 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Sat, 18 Oct 2008 12:39:48 +0200 (CEST) Subject: [pypy-svn] r59206 - in pypy/dist/pypy: lang/gameboy translator/goal Message-ID: <20081018103948.249DD16A084@codespeak.net> Author: cami Date: Sat Oct 18 12:39:47 2008 New Revision: 59206 Modified: pypy/dist/pypy/lang/gameboy/timer.py pypy/dist/pypy/translator/goal/targetgbprofiling.py Log: reverted previosly commited bug in gameboy timer targetgbprofiling doesn't print anymore opcode numbers Modified: pypy/dist/pypy/lang/gameboy/timer.py ============================================================================== --- pypy/dist/pypy/lang/gameboy/timer.py (original) +++ pypy/dist/pypy/lang/gameboy/timer.py Sat Oct 18 12:39:47 2008 @@ -156,5 +156,5 @@ pass def get_time(self): - return (time.time()*1000) + return int(time.time()*1000) Modified: pypy/dist/pypy/translator/goal/targetgbprofiling.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetgbprofiling.py (original) +++ pypy/dist/pypy/translator/goal/targetgbprofiling.py Sat Oct 18 12:39:47 2008 @@ -8,8 +8,7 @@ from pypy.lang.gameboy.interrupt import Interrupt from pypy.lang.gameboy.profiling.profiling_cpu import ProfilingCPU - - +PRINT_OPCODE_LABEL=False def entry_point(argv=None): typical = False @@ -48,13 +47,19 @@ for i in range(0xFF): if i not in forbidden and OP_CODES[i] is not None: op_codes[0] = i - print i, ":", run(op_codes, count) + if PRINT_OPCODE_LABEL: + print i, ":", run(op_codes, count) + else: + print run(op_codes, count) def run_each_second_order(count): op_codes = [0xCB]*2 for i in range(0xFF): op_codes[1] = i - print "0xCB :", i, ":" , run(op_codes, count) + if PRINT_OPCODE_LABEL: + print "0xCB :", i, ":" , run(op_codes, count) + else: + print run(op_codes, count) def run_all_first_order(count): print run(FIRST_ORDER_LIST, count) From antocuni at codespeak.net Sat Oct 18 14:11:38 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 18 Oct 2008 14:11:38 +0200 (CEST) Subject: [pypy-svn] r59207 - in pypy/branch/oo-jit/pypy/jit/codegen: cli/test test Message-ID: <20081018121138.A36F716A0D6@codespeak.net> Author: antocuni Date: Sat Oct 18 14:11:36 2008 New Revision: 59207 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py Log: add a test to rgenop that shows a bug of the cli backend Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py Sat Oct 18 14:11:36 2008 @@ -84,6 +84,8 @@ def test_interior_access(self): py.test.skip('fixme') + def test_switch_goto_parent_block_direct(self): + py.test.skip('fixme') class TestRCliGenopCompile(AbstractRGenOpTestsCompile): RGenOp = RCliGenOp @@ -143,3 +145,5 @@ def test_ovfcheck1_compile(self): py.test.skip('fixme') + def test_switch_goto_parent_block_compile(self): + py.test.skip('fixme') Modified: pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py Sat Oct 18 14:11:36 2008 @@ -501,6 +501,69 @@ return res return large_switch_runner + +def make_switch_goto_parent_block(T, rgenop): + """ + def f(v0, v1): + firstblock: # label + if v0 == 0: # switch + return 21*v1 + elif v0 == 1: + return 21+v1 + elif v0 == 2: + v0 = v0-1 + v1 = v1*2 + goto firstblock + else: + return v1 + """ + sigtoken = rgenop.sigToken(T.FUNC2) + builder, gv_switch, [gv0, gv1] = rgenop.newgraph(sigtoken, "switch") + builder.start_writing() + + args_gv = [gv0, gv1] + firstblock = builder.enter_next_block(args_gv) + gv0, gv1 = args_gv + + args_gv = [gv0, gv1] + flexswitch, default_builder = builder.flexswitch(gv0, args_gv) + gv0, gv1 = args_gv + + const21 = rgenop.genconst(21) + + # default + default_builder.finish_and_return(sigtoken, gv1) + # case == 0 + const0 = rgenop.genconst(0) + case_builder = flexswitch.add_case(const0) + gv_res_case0 = case_builder.genop2('int_mul', const21, gv1) + case_builder.finish_and_return(sigtoken, gv_res_case0) + # case == 1 + const1 = rgenop.genconst(1) + case_builder = flexswitch.add_case(const1) + gv_res_case1 = case_builder.genop2('int_add', const21, gv1) + case_builder.finish_and_return(sigtoken, gv_res_case1) + # case == 2 + const2 = rgenop.genconst(2) + case_builder = flexswitch.add_case(const2) + gv0_new = case_builder.genop2('int_sub', gv0, const1) + gv1_new = case_builder.genop2('int_mul', gv1, const2) + case_builder.finish_and_goto([gv0_new, gv1_new], firstblock) + + builder.end() + return gv_switch + +def get_switch_goto_parent_block_runner(T, RGenOp): + def switch_goto_parent_block_runner(x, y): + rgenop = RGenOp() + gv_switchfn = make_switch_goto_parent_block(T, rgenop) + switchfn = gv_switchfn.revealconst(T.Ptr(T.FUNC2)) + res = switchfn(x, y) + keepalive_until_here(rgenop) # to keep the code blocks alive + return res + return switch_goto_parent_block_runner + + def make_fact(T, rgenop): # def fact(x): # if x: @@ -1167,6 +1230,18 @@ res = fn(42, 18) assert res == 18 + def test_switch_goto_parent_block_compile(self): + fn = self.compile(get_switch_goto_parent_block_runner(self.T, self.RGenOp), [int, int]) + res = fn(0, 2) + assert res == 42 + res = fn(1, 16) + assert res == 37 + res = fn(2, 15) + assert res == 51 + res = fn(42, 16) + assert res == 16 + + def test_fact_compile(self): fn = self.compile(get_fact_runner(self.T, self.RGenOp), [int]) res = fn(2) @@ -1407,6 +1482,19 @@ res = fnptr(42, 16, 3, 4, 5) assert res == 16 + def test_switch_goto_parent_block_direct(self): + rgenop = self.RGenOp() + gv_switchfn = make_switch_goto_parent_block(self.T, rgenop) + fnptr = self.cast(gv_switchfn, 2) + res = fnptr(0, 2) + assert res == 42 + res = fnptr(1, 16) + assert res == 37 + res = fnptr(2, 15) + assert res == 51 + res = fnptr(42, 16) + assert res == 16 + def test_large_switch_direct(self): rgenop = self.RGenOp() gv_switchfn = make_large_switch(self.T, rgenop) From afa at codespeak.net Sat Oct 18 16:10:24 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 18 Oct 2008 16:10:24 +0200 (CEST) Subject: [pypy-svn] r59210 - pypy/branch/cbuild-refactor/pypy/translator/c Message-ID: <20081018141024.3B84216A0E4@codespeak.net> Author: afa Date: Sat Oct 18 16:10:22 2008 New Revision: 59210 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Log: It works much better this way Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Sat Oct 18 16:10:22 2008 @@ -281,7 +281,7 @@ # The module must be kept alive with the function. # This wrapper avoids creating a cycle. class Wrapper: - def __init__(self): + def __init__(self, obj): self.mod = mod self.func = obj def __call__(self, *args, **kwargs): From pedronis at codespeak.net Sat Oct 18 16:34:29 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 18 Oct 2008 16:34:29 +0200 (CEST) Subject: [pypy-svn] r59212 - in pypy/build/testrunner: . test Message-ID: <20081018143429.95E8616A08F@codespeak.net> Author: pedronis Date: Sat Oct 18 16:34:29 2008 New Revision: 59212 Modified: pypy/build/testrunner/runner.py pypy/build/testrunner/test/test_runner.py Log: tell which tests are being started Modified: pypy/build/testrunner/runner.py ============================================================================== --- pypy/build/testrunner/runner.py (original) +++ pypy/build/testrunner/runner.py Sat Oct 18 16:34:29 2008 @@ -66,6 +66,7 @@ except IndexError: result_queue.put(None) # done return + result_queue.put(('start', test)) basename = py.path.local(test).purebasename logfname = sessdir.join("%d-%s-pytest-log" % (num, basename)) one_output = sessdir.join("%d-%s-output" % (num, basename)) @@ -87,7 +88,7 @@ if extralog: logdata += extralog - result_queue.put((failure, logdata, output)) + result_queue.put(('done', test, failure, logdata, output)) invoke_in_thread = thread.start_new_thread @@ -110,7 +111,6 @@ result_queue =start_workers(N, run_param, testdirs) done = 0 - first_ever = True while True: res = result_queue.get() if res is None: @@ -118,14 +118,17 @@ if done == N: break continue - - somefailed, logdata, output = res + + if res[0] == 'start': + out.write("++ starting %s\n" % res[1]) + continue + + testname, somefailed, logdata, output = res[1:] failure = failure or somefailed - if first_ever: - first_ever = False - else: - out.write(79*'_'+'\n') + heading = "__ %s " % testname + + out.write(heading + (79-len(heading))*'_'+'\n') out.write(output) if logdata: Modified: pypy/build/testrunner/test/test_runner.py ============================================================================== --- pypy/build/testrunner/test/test_runner.py (original) +++ pypy/build/testrunner/test/test_runner.py Sat Oct 18 16:34:29 2008 @@ -154,10 +154,12 @@ out_lines = out.getvalue().splitlines() - assert len(out_lines) == 1 + assert len(out_lines) == 3 - assert out_lines[0].startswith("run [") - assert "test_normal" in out_lines[0] + assert out_lines[0].startswith("++ starting") + assert out_lines[2].startswith("run [") + for line in out_lines: + assert "test_normal" in line def test_many_dirs(self): test_driver = [py.path.local(py.__file__).dirpath('bin', 'py.test')] From pedronis at codespeak.net Sat Oct 18 16:37:00 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 18 Oct 2008 16:37:00 +0200 (CEST) Subject: [pypy-svn] r59213 - pypy/build/bot2/pypybuildbot Message-ID: <20081018143700.2442F16A0E4@codespeak.net> Author: pedronis Date: Sat Oct 18 16:36:59 2008 New Revision: 59213 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: try increasing timeout Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Sat Oct 18 16:36:59 2008 @@ -91,6 +91,7 @@ "--config=~/machine_cfg.py", "--root=pypy"], logfiles={'pytestLog': 'testrun.log'}, + timeout = 2400, env={"PYTHONPATH": ['.']})) class PyPyTranslaledLibPythonTestFactory(factory.BuildFactory): From pedronis at codespeak.net Sun Oct 19 00:21:00 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 19 Oct 2008 00:21:00 +0200 (CEST) Subject: [pypy-svn] r59225 - pypy/build/bot2/pypybuildbot Message-ID: <20081018222100.870EE16A045@codespeak.net> Author: pedronis Date: Sun Oct 19 00:21:00 2008 New Revision: 59225 Modified: pypy/build/bot2/pypybuildbot/master.py Log: allow only wyvern for now, trying to see if it makes a differece with our test hanging issues Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Sun Oct 19 00:21:00 2008 @@ -49,7 +49,7 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["wyvern", "cobra"], + "slavenames": ["wyvern"], "builddir": LINUX32, "factory": pypyOwnTestFactory }, From fijal at codespeak.net Sun Oct 19 12:15:51 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 19 Oct 2008 12:15:51 +0200 (CEST) Subject: [pypy-svn] r59227 - pypy/branch/cbuild-refactor/pypy/config Message-ID: <20081019101551.2A29716A15D@codespeak.net> Author: fijal Date: Sun Oct 19 12:15:49 2008 New Revision: 59227 Modified: pypy/branch/cbuild-refactor/pypy/config/pypyoption.py Log: * Leave a deprecation comment * Remove bz2 from working modules on windows for now Modified: pypy/branch/cbuild-refactor/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/config/pypyoption.py (original) +++ pypy/branch/cbuild-refactor/pypy/config/pypyoption.py Sun Oct 19 12:15:49 2008 @@ -36,12 +36,16 @@ ["md5", "sha", "cStringIO", "itertools"] )) +# XXX this should move somewhere else, maybe to platform ("is this posixish" +# check or something) if sys.platform == "win32": # unix only modules del working_modules["crypt"] del working_modules["fcntl"] del working_modules["termios"] del working_modules["_minimal_curses"] + # XXX this is temporary, hopefully + del working_modules["bz2"] if sys.platform == "sunos5": del working_modules['mmap'] # depend on ctypes, can'T get at c-level 'errono' From pedronis at codespeak.net Sun Oct 19 15:11:55 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 19 Oct 2008 15:11:55 +0200 (CEST) Subject: [pypy-svn] r59231 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081019131155.875A716A1EC@codespeak.net> Author: pedronis Date: Sun Oct 19 15:11:54 2008 New Revision: 59231 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Log: - pass -mdynamic-no-pic when we build standalone on darwin - tentative fix to tuatara problem, to test there Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Sun Oct 19 15:11:54 2008 @@ -7,7 +7,8 @@ link_flags = [] cflags = ['-O3', '-fomit-frame-pointer'] - # -mdynamic-no-pic for standalone + standalone_only = ['-mdynamic-no-pic'] + shared_only = ['-mmacosx-version-min=10.4'] def __init__(self, cc=None): if cc is None: @@ -15,7 +16,8 @@ self.cc = cc def _args_for_shared(self, args): - return ['-bundle', '-undefined', 'dynamic_lookup'] + args + return (self.shared_only + ['-bundle', '-undefined', 'dynamic_lookup'] + + args) def include_dirs_for_libffi(self): return ['/usr/include/ffi'] Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Sun Oct 19 15:11:54 2008 @@ -97,6 +97,8 @@ link_flags = ['-pthread'] cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] + standalone_only = [] + shared_only = [] so_ext = 'so' exe_ext = '' @@ -114,10 +116,15 @@ def _includedirs(self, include_dirs): return ['-I%s' % (idir,) for idir in include_dirs] - def _compile_args_from_eci(self, eci): + def _compile_args_from_eci(self, eci, standalone): include_dirs = self._preprocess_dirs(eci.include_dirs) args = self._includedirs(include_dirs) - return (self.cflags + list(eci.compile_extra) + args) + if standalone: + extra = self.standalone_only + else: + extra = self.shared_only + cflags = self.cflags + extra + return (cflags + list(eci.compile_extra) + args) def _link_args_from_eci(self, eci): library_dirs = self._libdirs(eci.library_dirs) @@ -132,17 +139,17 @@ def _args_for_shared(self, args): return ['-shared'] + args - def _compile_o_files(self, cfiles, eci): + def _compile_o_files(self, cfiles, eci, standalone=True): cfiles = [py.path.local(f) for f in cfiles] cfiles += [py.path.local(f) for f in eci.separate_module_files] - compile_args = self._compile_args_from_eci(eci) + compile_args = self._compile_args_from_eci(eci, standalone) ofiles = [] for cfile in cfiles: ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) return ofiles def compile(self, cfiles, eci, outputfilename=None, standalone=True): - ofiles = self._compile_o_files(cfiles, eci) + ofiles = self._compile_o_files(cfiles, eci, standalone) return self._finish_linking(ofiles, eci, outputfilename, standalone) def _finish_linking(self, ofiles, eci, outputfilename, standalone): From pedronis at codespeak.net Sun Oct 19 15:42:40 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 19 Oct 2008 15:42:40 +0200 (CEST) Subject: [pypy-svn] r59232 - pypy/branch/cbuild-refactor/pypy/translator/c/src Message-ID: <20081019134240.BDAC716A032@codespeak.net> Author: pedronis Date: Sun Oct 19 15:42:40 2008 New Revision: 59232 Added: pypy/branch/cbuild-refactor/pypy/translator/c/src/allocator.h - copied, changed from r59227, pypy/branch/cbuild-refactor/pypy/translator/c/src/standalone.h Modified: pypy/branch/cbuild-refactor/pypy/translator/c/src/g_include.h pypy/branch/cbuild-refactor/pypy/translator/c/src/standalone.h Log: tweak to fix the test_standalone failure on darwin Copied: pypy/branch/cbuild-refactor/pypy/translator/c/src/allocator.h (from r59227, pypy/branch/cbuild-refactor/pypy/translator/c/src/standalone.h) ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/src/standalone.h (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/src/allocator.h Sun Oct 19 15:42:40 2008 @@ -1,9 +1,4 @@ -#include -#include -#include -#include - #ifndef PYPY_NOT_MAIN_FILE #ifdef AVR #ifndef NO_OBMALLOC Modified: pypy/branch/cbuild-refactor/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/src/g_include.h (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/src/g_include.h Sun Oct 19 15:42:40 2008 @@ -60,6 +60,7 @@ #endif #ifdef PYPY_STANDALONE +# include "src/allocator.h" # include "src/main.h" #endif Modified: pypy/branch/cbuild-refactor/pypy/translator/c/src/standalone.h ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/src/standalone.h (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/src/standalone.h Sun Oct 19 15:42:40 2008 @@ -4,32 +4,7 @@ #include #include -#ifndef PYPY_NOT_MAIN_FILE -#ifdef AVR - #ifndef NO_OBMALLOC - #define NO_OBMALLOC - #endif -#endif - -#if defined(TRIVIAL_MALLOC_DEBUG) - void *PyObject_Malloc(size_t n) { return malloc(n); } - void *PyObject_Realloc(void *p, size_t n) { return realloc(p, n); } - void PyObject_Free(void *p) { if (p) { *((int*)p) = 0xDDDDDDDD; } free(p); } - -#elif defined(LINUXMEMCHK) -# include "linuxmemchk.c" - -#elif defined(NO_OBMALLOC) - void *PyObject_Malloc(size_t n) { return malloc(n); } - void *PyObject_Realloc(void *p, size_t n) { return realloc(p, n); } - void PyObject_Free(void *p) { free(p); } - -#else -# ifndef WITH_PYMALLOC -# define WITH_PYMALLOC -# endif -# include "obmalloc.c" - -#endif - -#endif +/* allocation functions prototypes */ +void *PyObject_Malloc(size_t n); +void *PyObject_Realloc(void *p, size_t n); +void PyObject_Free(void *p); From pedronis at codespeak.net Sun Oct 19 16:24:23 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 19 Oct 2008 16:24:23 +0200 (CEST) Subject: [pypy-svn] r59233 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081019142423.696AB16A000@codespeak.net> Author: pedronis Date: Sun Oct 19 16:24:21 2008 New Revision: 59233 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Log: __thread is known not to be supported currently on darwin Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Sun Oct 19 16:24:21 2008 @@ -24,3 +24,8 @@ def library_dirs_for_libffi(self): return [] + + def check___thread(self): + # currently __thread is not supported by Darwin gccs + return False + From pedronis at codespeak.net Sun Oct 19 16:24:53 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 19 Oct 2008 16:24:53 +0200 (CEST) Subject: [pypy-svn] r59234 - in pypy/branch/cbuild-refactor/pypy: config translator/platform Message-ID: <20081019142453.BC80B16A020@codespeak.net> Author: pedronis Date: Sun Oct 19 16:24:53 2008 New Revision: 59234 Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Log: avoid some code duplication Modified: pypy/branch/cbuild-refactor/pypy/config/translationoption.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/config/translationoption.py (original) +++ pypy/branch/cbuild-refactor/pypy/config/translationoption.py Sun Oct 19 16:24:53 2008 @@ -362,15 +362,7 @@ set_platform(config.translation.platform, config.translation.cc) def get_platform(config): + from pypy.translator.platform import pick_platform opt = config.translation.platform - if opt == 'maemo': - from pypy.translator.platform.maemo import Maemo - return Maemo(config.translation.cc) - elif opt == 'host': - from pypy.translator.platform import host - return host.__class__(config.translation.cc) - elif opt == 'distutils': - from pypy.translator.platform.distutils_platform import DistutilsPlatform - return DistutilsPlatform(config.translation.cc) - else: - raise ValueError(opt) + cc = config.translation.cc + return pick_platform(opt, cc) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Sun Oct 19 16:24:53 2008 @@ -103,18 +103,21 @@ platform = host -def set_platform(new_platform, cc): - global platform - log.msg("Setting platform to %r cc=%s" % (new_platform,cc)) +def pick_platform(new_platform, cc): if new_platform == 'host': - platform = host.__class__(cc) + return host.__class__(cc) elif new_platform == 'maemo': from pypy.translator.platform.maemo import Maemo - platform = Maemo(cc) + return Maemo(cc) elif new_platform == 'distutils': from pypy.translator.platform.distutils_platform import DistutilsPlatform - platform = DistutilsPlatform() + return DistutilsPlatform() else: - raise NotImplementedError("platform = %s" % (new_platform,)) + raise ValueError("platform = %s" % (new_platform,)) + +def set_platform(new_platform, cc): + global platform + log.msg("Setting platform to %r cc=%s" % (new_platform,cc)) + platform = pick_platform(new_platform, cc) From pedronis at codespeak.net Sun Oct 19 17:11:29 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 19 Oct 2008 17:11:29 +0200 (CEST) Subject: [pypy-svn] r59237 - in pypy/build/testrunner: . test Message-ID: <20081019151129.6FE6316A1BE@codespeak.net> Author: pedronis Date: Sun Oct 19 17:11:27 2008 New Revision: 59237 Modified: pypy/build/testrunner/runner.py pypy/build/testrunner/test/test_runner.py Log: print even more progress/debugging info Modified: pypy/build/testrunner/runner.py ============================================================================== --- pypy/build/testrunner/runner.py (original) +++ pypy/build/testrunner/runner.py Sun Oct 19 17:11:27 2008 @@ -107,26 +107,36 @@ N = run_param.parallel_runs failure = False - - result_queue =start_workers(N, run_param, testdirs) + + for testname in testdirs: + out.write("-- %s\n" % testname) + out.write("-- %d to run\n" % len(testdirs)) + + result_queue = start_workers(N, run_param, testdirs) done = 0 + started = 0 + + worker_done = 0 while True: res = result_queue.get() if res is None: - done += 1 - if done == N: + worker_done += 1 + if worker_done == N: break continue if res[0] == 'start': - out.write("++ starting %s\n" % res[1]) + started += 1 + out.write("++ starting %s [%d started in total]\n" % (res[1], + started)) continue testname, somefailed, logdata, output = res[1:] + done += 1 failure = failure or somefailed - heading = "__ %s " % testname + heading = "__ %s [%d done in total] " % (testname, done) out.write(heading + (79-len(heading))*'_'+'\n') @@ -224,6 +234,7 @@ if py.path.local(config_py_file).check(file=1): print >>out, "using config", config_py_file execfile(config_py_file, run_param.__dict__) + run_param.__dict__.pop('__builtins__', None) run_param.collect_testdirs(testdirs) Modified: pypy/build/testrunner/test/test_runner.py ============================================================================== --- pypy/build/testrunner/test/test_runner.py (original) +++ pypy/build/testrunner/test/test_runner.py Sun Oct 19 17:11:27 2008 @@ -154,11 +154,11 @@ out_lines = out.getvalue().splitlines() - assert len(out_lines) == 3 + assert len(out_lines) == 5 - assert out_lines[0].startswith("++ starting") - assert out_lines[2].startswith("run [") - for line in out_lines: + assert out_lines[2].startswith("++ starting") + assert out_lines[4].startswith("run [") + for line in out_lines[2:]: assert "test_normal" in line def test_many_dirs(self): From pedronis at codespeak.net Sun Oct 19 17:23:02 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 19 Oct 2008 17:23:02 +0200 (CEST) Subject: [pypy-svn] r59238 - pypy/build/bot2/pypybuildbot Message-ID: <20081019152302.C7258169F6D@codespeak.net> Author: pedronis Date: Sun Oct 19 17:23:02 2008 New Revision: 59238 Modified: pypy/build/bot2/pypybuildbot/builds.py pypy/build/bot2/pypybuildbot/summary.py Log: try to dinstinguish aborted test runs Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Sun Oct 19 17:23:02 2008 @@ -3,6 +3,15 @@ from buildbot.status.builder import SUCCESS +class ShellCmd(shell.ShellCommand): + # our own version that can distinguish abort cases (rc == -1) + + def getText(self, cmd, results): + if cmd.rc == -1: + return self.describe(True) + ['aborted'] + return shell.ShellCommand.getText(self, cmd, results) + + class FirstTime(shell.SetProperty): def __init__(self, **kwds): @@ -17,22 +26,22 @@ command = "if not exist pypy echo yes" -class CondShellCommand(shell.ShellCommand): +class CondShellCommand(ShellCmd): def __init__(self, **kwds): - shell.ShellCommand.__init__(self, **kwds) + ShellCmd.__init__(self, **kwds) self.cond = kwds.get('cond', lambda props: True) def start(self): props = self.build.getProperties() yes = self.cond(props) if yes: - shell.ShellCommand.start(self) + ShellCmd.start(self) else: self.setStatus(None, SUCCESS) self.finished(SUCCESS) -class Translate(shell.ShellCommand): +class Translate(ShellCmd): name = "translate" description = ["translating"] descriptionDone = ["translation"] @@ -47,7 +56,7 @@ kw['translationArgs'] = translationArgs kw['targetArgs'] = targetArgs kw['timeout'] = 3600 - shell.ShellCommand.__init__(self, workdir, *a, **kw) + ShellCmd.__init__(self, workdir, *a, **kw) self.command = (self.command + translationArgs + [self.translationTarget] + targetArgs) @@ -83,7 +92,7 @@ setup_steps(platform, self) - self.addStep(shell.ShellCommand( + self.addStep(ShellCmd( description="pytest", command=["python", "testrunner/runner.py", "--logfile=testrun.log", @@ -104,7 +113,7 @@ self.addStep(Translate(["-O2"], [])) - self.addStep(shell.ShellCommand( + self.addStep(ShellCmd( description="lib-python test", command=["python", "pypy/test_all.py", "--pypy=pypy/translator/goal/pypy-c", Modified: pypy/build/bot2/pypybuildbot/summary.py ============================================================================== --- pypy/build/bot2/pypybuildbot/summary.py (original) +++ pypy/build/bot2/pypybuildbot/summary.py Sun Oct 19 17:23:02 2008 @@ -97,11 +97,14 @@ pytest_log = None stdio_log = None failure = None + aborted = False for step in build.getSteps(): logs = dict((log.getName(), log) for log in step.getLogs()) if 'pytestLog' in logs: - pytest_log = logs['pytestLog'] stdio_log = logs['stdio'] + if 'aborted' in step.getText(): + aborted = True + pytest_log = logs['pytestLog'] break elif (stdio_log is None and step.getResults()[0] in (FAILURE, EXCEPTION)): @@ -120,6 +123,8 @@ name = failure or '' outcome_set.populate_one(name, '!', "no log from the test run") else: + if aborted: + outcome_set.populate_one(' aborted', '!', "") outcome_set.populate(pytest_log) return outcome_set From afa at codespeak.net Sun Oct 19 18:35:24 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Sun, 19 Oct 2008 18:35:24 +0200 (CEST) Subject: [pypy-svn] r59239 - pypy/branch/cbuild-refactor/pypy/translator Message-ID: <20081019163524.CC24B16A25A@codespeak.net> Author: afa Date: Sun Oct 19 18:35:22 2008 New Revision: 59239 Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py Log: Translation fix for Windows Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/driver.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/driver.py Sun Oct 19 18:35:22 2008 @@ -859,5 +859,5 @@ def mkexename(name): if sys.platform == 'win32': - name = os.path.normpath(name + '.exe') + name = os.path.normpath(str(name) + '.exe') return name From fijal at codespeak.net Sun Oct 19 18:38:36 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 19 Oct 2008 18:38:36 +0200 (CEST) Subject: [pypy-svn] r59240 - pypy/branch/cbuild-refactor/pypy/translator Message-ID: <20081019163836.A0ABB169F53@codespeak.net> Author: fijal Date: Sun Oct 19 18:38:36 2008 New Revision: 59240 Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py Log: Pass around py.path.local, not str Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/driver.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/driver.py Sun Oct 19 18:38:36 2008 @@ -859,5 +859,5 @@ def mkexename(name): if sys.platform == 'win32': - name = os.path.normpath(str(name) + '.exe') + name = name.new(ext='exe') return name From pedronis at codespeak.net Sun Oct 19 19:52:23 2008 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 19 Oct 2008 19:52:23 +0200 (CEST) Subject: [pypy-svn] r59241 - pypy/build/bot2 Message-ID: <20081019175223.D33D716A26C@codespeak.net> Author: pedronis Date: Sun Oct 19 19:52:20 2008 New Revision: 59241 Modified: pypy/build/bot2/TODO Log: something to clarify Modified: pypy/build/bot2/TODO ============================================================================== --- pypy/build/bot2/TODO (original) +++ pypy/build/bot2/TODO Sun Oct 19 19:52:20 2008 @@ -16,6 +16,8 @@ - wire windows slave IN-PROGRESS +- slave for own test need pexect (seems not to be there on wyvern's python?) + - convention for naming and coalescing alternative builders for the same build - implement pre-switch logic to avoid the full checkouts when running non default branches From fijal at codespeak.net Sun Oct 19 19:52:43 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 19 Oct 2008 19:52:43 +0200 (CEST) Subject: [pypy-svn] r59242 - pypy/branch/cbuild-refactor/pypy/translator Message-ID: <20081019175243.AA69A16A26C@codespeak.net> Author: fijal Date: Sun Oct 19 19:52:42 2008 New Revision: 59242 Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py Log: use py.path.local here as well Modified: pypy/branch/cbuild-refactor/pypy/translator/driver.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/driver.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/driver.py Sun Oct 19 19:52:42 2008 @@ -507,7 +507,7 @@ newexename = self.exe_name % self.get_info() if '/' not in newexename and '\\' not in newexename: newexename = './' + newexename - return mkexename(newexename) + return mkexename(py.path.local(newexename)) def create_exe(self): if self.exe_name is not None: From fijal at codespeak.net Sun Oct 19 21:16:48 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 19 Oct 2008 21:16:48 +0200 (CEST) Subject: [pypy-svn] r59243 - pypy/branch/cbuild-refactor/pypy Message-ID: <20081019191648.7BF0C16A04B@codespeak.net> Author: fijal Date: Sun Oct 19 21:16:47 2008 New Revision: 59243 Modified: pypy/branch/cbuild-refactor/pypy/TODO.beformerge Log: update todo Modified: pypy/branch/cbuild-refactor/pypy/TODO.beformerge ============================================================================== --- pypy/branch/cbuild-refactor/pypy/TODO.beformerge (original) +++ pypy/branch/cbuild-refactor/pypy/TODO.beformerge Sun Oct 19 21:16:47 2008 @@ -1,3 +1 @@ -* Move distutils support into distutils platform -* Make sure ctypes_configure is working -* Check why socket test is hanging (and if it's handing on dist/trunk as well) \ No newline at end of file +* Check why socket test is hanging (and if it's handing on dist/trunk as well) From fijal at codespeak.net Sun Oct 19 21:17:18 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 19 Oct 2008 21:17:18 +0200 (CEST) Subject: [pypy-svn] r59244 - pypy/branch/cbuild-refactor/pypy Message-ID: <20081019191718.8702416A04B@codespeak.net> Author: fijal Date: Sun Oct 19 21:17:17 2008 New Revision: 59244 Modified: pypy/branch/cbuild-refactor/pypy/TODO.beformerge Log: add this Modified: pypy/branch/cbuild-refactor/pypy/TODO.beformerge ============================================================================== --- pypy/branch/cbuild-refactor/pypy/TODO.beformerge (original) +++ pypy/branch/cbuild-refactor/pypy/TODO.beformerge Sun Oct 19 21:17:17 2008 @@ -1 +1,2 @@ * Check why socket test is hanging (and if it's handing on dist/trunk as well) +* Change inheritance hierarchy, so Linux is not a base class \ No newline at end of file From afa at codespeak.net Sun Oct 19 23:20:57 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Sun, 19 Oct 2008 23:20:57 +0200 (CEST) Subject: [pypy-svn] r59245 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081019212057.B6C81169F02@codespeak.net> Author: afa Date: Sun Oct 19 23:20:55 2008 New Revision: 59245 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: Correct a problem spotted by xorAxAx, when another OS tries to import windows.py Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Sun Oct 19 23:20:55 2008 @@ -5,25 +5,20 @@ from pypy.translator.platform import log, _run_subprocess from pypy.tool import autopath -def _get_msvc_tools(): +def _install_msvc_env(): # The same compiler must be used for the python interpreter # and extension modules msc_pos = sys.version.find('MSC v.') if msc_pos == -1: # Not a windows platform... - return None + return msc_ver = int(sys.version[msc_pos+6:msc_pos+10]) # 1300 -> 70, 1310 -> 71, 1400 -> 80, 1500 -> 90 vsver = (msc_ver / 10) - 60 - return os.environ['VS%sCOMNTOOLS' % vsver] + toolsdir = os.environ['VS%sCOMNTOOLS' % vsver] + vcvars = os.path.join(toolsdir, 'vsvars32.bat') -def _install_msvc_env(): - - vcvars = os.path.join(_get_msvc_tools(), 'vsvars32.bat') - if not vcvars: - return - import subprocess popen = subprocess.Popen('"%s" & set' % (vcvars,), stdout=subprocess.PIPE, @@ -38,6 +33,7 @@ key, value = line.split('=', 1) if key.upper() in ['PATH', 'INCLUDE', 'LIB']: os.environ[key] = value + log.msg(line) log.msg("Updated environment with %s" % (vcvars,)) try: From fijal at codespeak.net Mon Oct 20 10:42:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 10:42:33 +0200 (CEST) Subject: [pypy-svn] r59251 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020084233.6596A169F98@codespeak.net> Author: fijal Date: Mon Oct 20 10:42:32 2008 New Revision: 59251 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: shuffle stuff around not to pretend that every platform inherits from linux Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Mon Oct 20 10:42:32 2008 @@ -49,10 +49,13 @@ name = "abstract platform" def __init__(self, cc): + if self.__class__ is Platform: + raise TypeError("You should not instantiate Platform class directly") self.cc = cc - + def compile(self, cfiles, eci, outputfilename=None, standalone=True): - raise NotImplementedError("Pure abstract baseclass") + ofiles = self._compile_o_files(cfiles, eci, standalone) + return self._finish_linking(ofiles, eci, outputfilename, standalone) def execute(self, executable, args=None, env=None): returncode, stdout, stderr = _run_subprocess(str(executable), args, @@ -75,6 +78,42 @@ return (self.__class__ is other.__class__ and self.__dict__ == other.__dict__) + # some helpers which seem to be cross-platform enough + + def _execute_c_compiler(self, cc, args, outname): + log.execute(cc + ' ' + ' '.join(args)) + returncode, stdout, stderr = _run_subprocess(cc, args) + self._handle_error(returncode, stderr, stdout, outname) + + def _handle_error(self, returncode, stderr, stdout, outname): + if returncode != 0: + errorfile = outname.new(ext='errors') + errorfile.write(stderr) + stderrlines = stderr.splitlines() + for line in stderrlines[:5]: + log.ERROR(line) + if len(stderrlines) > 5: + log.ERROR('...') + raise CompilationError(stdout, stderr) + + + def _compile_args_from_eci(self, eci, standalone): + include_dirs = self._preprocess_dirs(eci.include_dirs) + args = self._includedirs(include_dirs) + if standalone: + extra = self.standalone_only + else: + extra = self.shared_only + cflags = self.cflags + extra + return (cflags + list(eci.compile_extra) + args) + + def _link_args_from_eci(self, eci): + library_dirs = self._libdirs(eci.library_dirs) + libraries = self._libs(eci.libraries) + return (library_dirs + libraries + self.link_flags + + list(eci.link_extra)) + + # below are some detailed informations for platforms def include_dirs_for_libffi(self): Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Mon Oct 20 10:42:32 2008 @@ -1,8 +1,8 @@ import py, os -from pypy.translator.platform import linux # xxx +from pypy.translator.platform import posix -class Darwin(linux.Linux): # xxx +class Darwin(posix.BasePosix): name = "darwin" link_flags = [] Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Mon Oct 20 10:42:32 2008 @@ -3,96 +3,9 @@ from pypy.translator.platform import Platform, CompilationError, ExecutionResult from pypy.translator.platform import log, _run_subprocess from pypy.tool import autopath +from pypy.translator.platform.posix import GnuMakefile, BasePosix -class Definition(object): - def __init__(self, name, value): - self.name = name - self.value = value - - def write(self, f): - def write_list(prefix, lst): - for i, fn in enumerate(lst): - print >> f, prefix, fn, - if i < len(lst)-1: - print >> f, '\\' - else: - print >> f - prefix = ' ' * len(prefix) - name, value = self.name, self.value - if isinstance(value, str): - f.write('%s = %s\n' % (name, value)) - else: - write_list('%s =' % (name,), value) - if value: - f.write('\n') - -class Rule(object): - def __init__(self, target, deps, body): - self.target = target - self.deps = deps - self.body = body - - def write(self, f): - target, deps, body = self.target, self.deps, self.body - if isinstance(deps, str): - dep_s = deps - else: - dep_s = ' '.join(deps) - f.write('%s: %s\n' % (target, dep_s)) - if isinstance(body, str): - f.write('\t%s\n' % body) - elif body: - f.write('\t%s\n' % '\n\t'.join(body)) - f.write('\n') - -class Comment(object): - def __init__(self, body): - self.body = body - - def write(self, f): - f.write('# %s\n' % (self.body,)) - -class GnuMakefile(object): - def __init__(self, path=None): - self.defs = {} - self.lines = [] - self.makefile_dir = py.path.local(path) - - def pathrel(self, fpath): - if fpath.dirpath() == self.makefile_dir: - return fpath.basename - elif fpath.dirpath().dirpath() == self.makefile_dir.dirpath(): - return '../' + fpath.relto(self.makefile_dir.dirpath()) - else: - return str(fpath) - - def definition(self, name, value): - defs = self.defs - defn = Definition(name, value) - if name in defs: - self.lines[defs[name]] = defn - else: - defs[name] = len(self.lines) - self.lines.append(defn) - - def rule(self, target, deps, body): - self.lines.append(Rule(target, deps, body)) - - def comment(self, body): - self.lines.append(Comment(body)) - - def write(self, out=None): - if out is None: - f = self.makefile_dir.join('Makefile').open('w') - else: - f = out - for line in self.lines: - line.write(f) - f.flush() - if out is None: - f.close() - -class Linux(Platform): +class Linux(BasePosix): name = "linux" link_flags = ['-pthread'] @@ -102,11 +15,6 @@ so_ext = 'so' exe_ext = '' - def __init__(self, cc=None): - if cc is None: - cc = 'gcc' - self.cc = cc - def _libs(self, libraries): return ['-l%s' % (lib,) for lib in libraries] @@ -163,37 +71,7 @@ exe_name += '.' + self.so_ext return self._link(self.cc, ofiles, self._link_args_from_eci(eci), standalone, exe_name) - - def _compile_c_file(self, cc, cfile, compile_args): - oname = cfile.new(ext='o') - args = ['-c'] + compile_args + [str(cfile), '-o', str(oname)] - self._execute_c_compiler(cc, args, oname) - return oname - - def _execute_c_compiler(self, cc, args, outname): - log.execute(cc + ' ' + ' '.join(args)) - returncode, stdout, stderr = _run_subprocess(cc, args) - self._handle_error(returncode, stderr, stdout, outname) - - def _handle_error(self, returncode, stderr, stdout, outname): - if returncode != 0: - errorfile = outname.new(ext='errors') - errorfile.write(stderr) - stderrlines = stderr.splitlines() - for line in stderrlines[:5]: - log.ERROR(line) - if len(stderrlines) > 5: - log.ERROR('...') - raise CompilationError(stdout, stderr) - def _link(self, cc, ofiles, link_args, standalone, exe_name): - args = [str(ofile) for ofile in ofiles] + link_args - args += ['-o', str(exe_name)] - if not standalone: - args = self._args_for_shared(args) - self._execute_c_compiler(cc, args, exe_name) - return exe_name - def gen_makefile(self, cfiles, eci, exe_name=None, path=None): cfiles = [py.path.local(f) for f in cfiles] cfiles += [py.path.local(f) for f in eci.separate_module_files] Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Mon Oct 20 10:42:32 2008 @@ -1,8 +1,8 @@ import py, os, sys -from pypy.translator.platform import linux # xxx from pypy.translator.platform import CompilationError, ExecutionResult from pypy.translator.platform import log, _run_subprocess +from pypy.translator.platform import Platform, posix from pypy.tool import autopath def _install_msvc_env(): @@ -44,7 +44,7 @@ traceback.print_exc() # Assume that the compiler is already part of the environment -class Windows(linux.Linux): # xxx +class Windows(Platform): name = "win32" so_ext = 'dll' exe_ext = 'exe' @@ -82,6 +82,15 @@ self._execute_c_compiler(cc, args, oname) return oname + def _compile_o_files(self, cfiles, eci, standalone=True): + cfiles = [py.path.local(f) for f in cfiles] + cfiles += [py.path.local(f) for f in eci.separate_module_files] + compile_args = self._compile_args_from_eci(eci, standalone) + ofiles = [] + for cfile in cfiles: + ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) + return ofiles + def _link(self, cc, ofiles, link_args, standalone, exe_name): args = ['/nologo'] + [str(ofile) for ofile in ofiles] + link_args args += ['/out:%s' % (exe_name,)] @@ -90,6 +99,18 @@ self._execute_c_compiler(self.link, args, exe_name) return exe_name + def _finish_linking(self, ofiles, eci, outputfilename, standalone): + if outputfilename is None: + outputfilename = ofiles[0].purebasename + exe_name = py.path.local(os.path.join(str(ofiles[0].dirpath()), + outputfilename)) + if standalone: + exe_name += '.' + self.exe_ext + else: + exe_name += '.' + self.so_ext + return self._link(self.cc, ofiles, self._link_args_from_eci(eci), + standalone, exe_name) + def _handle_error(self, returncode, stderr, stdout, outname): if returncode != 0: # Microsoft compilers write compilation errors to stdout @@ -178,5 +199,5 @@ self._handle_error(returncode, stdout, stderr, path.join('make')) -class NMakefile(linux.GnuMakefile): +class NMakefile(posix.GnuMakefile): pass # for the moment From fijal at codespeak.net Mon Oct 20 10:43:45 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 10:43:45 +0200 (CEST) Subject: [pypy-svn] r59252 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020084345.CEA2B169F92@codespeak.net> Author: fijal Date: Mon Oct 20 10:43:45 2008 New Revision: 59252 Added: pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py (contents, props changed) Log: Add missing file Added: pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py ============================================================================== --- (empty file) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py Mon Oct 20 10:43:45 2008 @@ -0,0 +1,181 @@ + +""" Base class for all posixish platforms +""" + +from pypy.translator.platform import Platform +import py + +class BasePosix(Platform): + def __init__(self, cc=None): + if cc is None: + cc = 'gcc' + self.cc = cc + + def _compile_c_file(self, cc, cfile, compile_args): + oname = cfile.new(ext='o') + args = ['-c'] + compile_args + [str(cfile), '-o', str(oname)] + self._execute_c_compiler(cc, args, oname) + return oname + + def _link(self, cc, ofiles, link_args, standalone, exe_name): + args = [str(ofile) for ofile in ofiles] + link_args + args += ['-o', str(exe_name)] + if not standalone: + args = self._args_for_shared(args) + self._execute_c_compiler(cc, args, exe_name) + return exe_name + + def gen_makefile(self, cfiles, eci, exe_name=None, path=None): + cfiles = [py.path.local(f) for f in cfiles] + cfiles += [py.path.local(f) for f in eci.separate_module_files] + + if path is None: + path = cfiles[0].dirpath() + + pypypath = py.path.local(autopath.pypydir) + + if exe_name is None: + exe_name = cfiles[0].new(ext=self.exe_ext) + + m = GnuMakefile(path) + m.exe_name = exe_name + m.eci = eci + + def pypyrel(fpath): + rel = py.path.local(fpath).relto(pypypath) + if rel: + return os.path.join('$(PYPYDIR)', rel) + else: + return fpath + + rel_cfiles = [m.pathrel(cfile) for cfile in cfiles] + rel_ofiles = [rel_cfile[:-2]+'.o' for rel_cfile in rel_cfiles] + m.cfiles = rel_cfiles + + rel_includedirs = [pypyrel(incldir) for incldir in + self._preprocess_dirs(eci.include_dirs)] + + m.comment('automatically generated makefile') + definitions = [ + ('PYPYDIR', autopath.pypydir), + ('TARGET', exe_name.basename), + ('DEFAULT_TARGET', '$(TARGET)'), + ('SOURCES', rel_cfiles), + ('OBJECTS', rel_ofiles), + ('LIBS', self._libs(eci.libraries)), + ('LIBDIRS', self._libdirs(eci.library_dirs)), + ('INCLUDEDIRS', self._includedirs(rel_includedirs)), + ('CFLAGS', self.cflags + list(eci.compile_extra)), + ('LDFLAGS', self.link_flags + list(eci.link_extra)), + ('CC', self.cc) + ] + for args in definitions: + m.definition(*args) + + rules = [ + ('all', '$(DEFAULT_TARGET)', []), + ('$(TARGET)', '$(OBJECTS)', '$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS)'), + ('%.o', '%.c', '$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)'), + ] + + for rule in rules: + m.rule(*rule) + + return m + + def execute_makefile(self, path_to_makefile): + if isinstance(path_to_makefile, GnuMakefile): + path = path_to_makefile.makefile_dir + else: + path = path_to_makefile + log.execute('make in %s' % (path,)) + returncode, stdout, stderr = _run_subprocess('make', ['-C', str(path)]) + self._handle_error(returncode, stdout, stderr, path.join('make')) + +class Definition(object): + def __init__(self, name, value): + self.name = name + self.value = value + + def write(self, f): + def write_list(prefix, lst): + for i, fn in enumerate(lst): + print >> f, prefix, fn, + if i < len(lst)-1: + print >> f, '\\' + else: + print >> f + prefix = ' ' * len(prefix) + name, value = self.name, self.value + if isinstance(value, str): + f.write('%s = %s\n' % (name, value)) + else: + write_list('%s =' % (name,), value) + if value: + f.write('\n') + +class Rule(object): + def __init__(self, target, deps, body): + self.target = target + self.deps = deps + self.body = body + + def write(self, f): + target, deps, body = self.target, self.deps, self.body + if isinstance(deps, str): + dep_s = deps + else: + dep_s = ' '.join(deps) + f.write('%s: %s\n' % (target, dep_s)) + if isinstance(body, str): + f.write('\t%s\n' % body) + elif body: + f.write('\t%s\n' % '\n\t'.join(body)) + f.write('\n') + +class Comment(object): + def __init__(self, body): + self.body = body + + def write(self, f): + f.write('# %s\n' % (self.body,)) + +class GnuMakefile(object): + def __init__(self, path=None): + self.defs = {} + self.lines = [] + self.makefile_dir = py.path.local(path) + + def pathrel(self, fpath): + if fpath.dirpath() == self.makefile_dir: + return fpath.basename + elif fpath.dirpath().dirpath() == self.makefile_dir.dirpath(): + return '../' + fpath.relto(self.makefile_dir.dirpath()) + else: + return str(fpath) + + def definition(self, name, value): + defs = self.defs + defn = Definition(name, value) + if name in defs: + self.lines[defs[name]] = defn + else: + defs[name] = len(self.lines) + self.lines.append(defn) + + def rule(self, target, deps, body): + self.lines.append(Rule(target, deps, body)) + + def comment(self, body): + self.lines.append(Comment(body)) + + def write(self, out=None): + if out is None: + f = self.makefile_dir.join('Makefile').open('w') + else: + f = out + for line in self.lines: + line.write(f) + f.flush() + if out is None: + f.close() From fijal at codespeak.net Mon Oct 20 10:57:50 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 10:57:50 +0200 (CEST) Subject: [pypy-svn] r59254 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020085750.08DF6169FC2@codespeak.net> Author: fijal Date: Mon Oct 20 10:57:48 2008 New Revision: 59254 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Log: make maemo more robust against different kind of arguments Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py Mon Oct 20 10:57:48 2008 @@ -62,8 +62,12 @@ self._handle_error(returncode, stderr, stdout, outname) def execute(self, executable, args=[], env=None): - args = [str(executable)] + args - log.message('executing /scratchbox/login ' + ' '.join(args)) + if isinstance(args, str): + args = str(executable) + ' ' + args + log.message('executing /scratchbox/login ' + args) + else: + args = [str(executable)] + args + log.message('executing /scratchbox/login ' + ' '.join(args)) returncode, stdout, stderr = _run_subprocess('/scratchbox/login', args, env) return ExecutionResult(returncode, stdout, stderr) From fijal at codespeak.net Mon Oct 20 11:05:29 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 11:05:29 +0200 (CEST) Subject: [pypy-svn] r59255 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020090529.C24F1169F95@codespeak.net> Author: fijal Date: Mon Oct 20 11:05:29 2008 New Revision: 59255 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Log: * Remove code duplication * Some support for 64 bit Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Mon Oct 20 11:05:29 2008 @@ -127,8 +127,12 @@ if sys.platform == 'linux2': - from pypy.translator.platform.linux import Linux - host = Linux() + from pypy.translator.platform.linux import Linux, Linux64 + import platform + if platform.architecture()[0] == '32bit': + host = Linux() + else: + host = Linux64() elif sys.platform == 'darwin': from pypy.translator.platform.darwin import Darwin host = Darwin() Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Mon Oct 20 11:05:29 2008 @@ -24,22 +24,6 @@ def _includedirs(self, include_dirs): return ['-I%s' % (idir,) for idir in include_dirs] - def _compile_args_from_eci(self, eci, standalone): - include_dirs = self._preprocess_dirs(eci.include_dirs) - args = self._includedirs(include_dirs) - if standalone: - extra = self.standalone_only - else: - extra = self.shared_only - cflags = self.cflags + extra - return (cflags + list(eci.compile_extra) + args) - - def _link_args_from_eci(self, eci): - library_dirs = self._libdirs(eci.library_dirs) - libraries = self._libs(eci.libraries) - return (library_dirs + libraries + self.link_flags + - list(eci.link_extra)) - def _preprocess_dirs(self, include_dirs): # hook for maemo return include_dirs @@ -144,3 +128,7 @@ def library_dirs_for_libffi(self): return ['/usr/lib/libffi'] + + +class Linux64(Linux): + shared_only = ['-fPIC'] From fijal at codespeak.net Mon Oct 20 11:07:30 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 11:07:30 +0200 (CEST) Subject: [pypy-svn] r59256 - pypy/branch/cbuild-refactor/pypy/translator/c/test Message-ID: <20081020090730.A2FE2169F9C@codespeak.net> Author: fijal Date: Mon Oct 20 11:07:29 2008 New Revision: 59256 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Log: this test is somewhere else these days Modified: pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/test/test_standalone.py Mon Oct 20 11:07:29 2008 @@ -266,32 +266,3 @@ def test_prof_inline(self): py.test.skip("Unsupported") - -def test_cross_compilation(): - py.test.skip("Skip for now") - from pypy.rlib.pyplatform import Platform - from pypy.config.translationoption import set_platform - - class X(Platform): - def get_compiler(self): - return 'x' - - def entry_point(argv): - return 0 - - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - - set_platform(t.config, X()) - try: - eci = ExternalCompilationInfo(platform=X()) - - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() - - makefile = udir.join(cbuilder.modulename, 'Makefile').read() - - m = re.search('^CC\s*=\s*x$', makefile) - finally: - set_platform(t.config, Platform()) From fijal at codespeak.net Mon Oct 20 12:55:51 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 12:55:51 +0200 (CEST) Subject: [pypy-svn] r59257 - pypy/dist/pypy/rpython/memory/gc Message-ID: <20081020105551.61978169F75@codespeak.net> Author: fijal Date: Mon Oct 20 12:55:48 2008 New Revision: 59257 Modified: pypy/dist/pypy/rpython/memory/gc/markcompact.py Log: Kill redzone hack. Now we have a proper solution that should shrink number of allocated pages as object sizes decrease Modified: pypy/dist/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/dist/pypy/rpython/memory/gc/markcompact.py Mon Oct 20 12:55:48 2008 @@ -46,6 +46,11 @@ # but compiles to the same pointer. Also we use raw_memmove in case # objects overlap. +# Exact algorithm for space resizing: we keep allocated more space than needed +# (2x, can be even more), but it's full of zeroes. After each collection, +# we bump next_collect_after which is a marker where to start each collection. +# It should be exponential (but less than 2) from the size occupied by objects + # in case we need to grow space, we use # current_space_size * FREE_SPACE_MULTIPLIER / FREE_SPACE_DIVIDER + needed FREE_SPACE_MULTIPLIER = 3 @@ -58,7 +63,7 @@ HDR = lltype.Struct('header', ('tid', lltype.Signed), ('forward_ptr', llmemory.Address)) - TRANSLATION_PARAMS = {'space_size': 2*1024*1024} # XXX adjust + TRANSLATION_PARAMS = {'space_size': 8*1024*1024} # XXX adjust malloc_zero_filled = True inline_simple_malloc = True @@ -70,7 +75,7 @@ def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096): MovingGCBase.__init__(self, config, chunk_size) self.space_size = space_size - self.red_zone = 0 + self.next_collect_after = space_size/2 # whatever... def setup(self): if self.config.gcconfig.debugprint: @@ -78,7 +83,7 @@ self.space = llarena.arena_malloc(self.space_size, True) ll_assert(bool(self.space), "couldn't allocate arena") self.free = self.space - self.top_of_space = self.space + self.space_size + self.top_of_space = self.space + self.next_collect_after MovingGCBase.setup(self) self.objects_with_finalizers = self.AddressDeque() self.objects_with_weakrefs = self.AddressStack() @@ -149,44 +154,41 @@ def try_obtain_free_space(self, needed): needed = raw_malloc_usage(needed) - missing = needed - (self.top_of_space - self.free) - if (self.red_zone >= 2 and self.increase_space_size(needed)): - return True - else: - self.markcompactcollect() - missing = needed - (self.top_of_space - self.free) - if missing <= 0: - return True # success - else: - # first check if the object could possibly fit - if not self.increase_space_size(needed): - return False - return True - - def new_space_size(self, incr): - return (self.space_size * FREE_SPACE_MULTIPLIER / - FREE_SPACE_DIVIDER + incr + FREE_SPACE_ADD) - - def increase_space_size(self, needed): - self.red_zone = 0 - new_size = self.new_space_size(needed) - newspace = llarena.arena_malloc(new_size, True) - if not newspace: - return False - self.tospace = newspace - self.space_size = new_size - self.markcompactcollect(resizing=True) - return True + while 1: + self.markcompactcollect(needed) + missing = needed - (self.top_of_space - self.free) + if missing < 0: + return True + + def new_space_size(self, occupied, needed): + return (occupied * FREE_SPACE_MULTIPLIER / + FREE_SPACE_DIVIDER + FREE_SPACE_ADD + needed) + + def double_space_size(self, minimal_size): + while self.space_size <= minimal_size: + self.space_size *= 2 + toaddr = llarena.arena_malloc(self.space_size, True) + return toaddr + + def compute_size_of_alive_objects(self): + fromaddr = self.space + totalsize = 0 + while fromaddr < self.free: + size_gc_header = self.gcheaderbuilder.size_gc_header + hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) + obj = fromaddr + size_gc_header + objsize = self.get_size(obj) + objtotalsize = size_gc_header + objsize + if self.marked(obj): + totalsize += raw_malloc_usage(objtotalsize) + fromaddr += objtotalsize + return totalsize def collect(self): self.markcompactcollect() - def markcompactcollect(self, resizing=False): + def markcompactcollect(self, needed=0): start_time = self.debug_collect_start() self.debug_check_consistency() - if resizing: - toaddr = self.tospace - else: - toaddr = llarena.arena_new_view(self.space) self.to_see = self.AddressStack() self.mark_roots_recursively() if (self.objects_with_finalizers.non_empty() or @@ -194,6 +196,15 @@ self.mark_objects_with_finalizers() self._trace_and_mark() self.to_see.delete() + totalsize = self.new_space_size(self.compute_size_of_alive_objects(), + needed) + if totalsize >= self.space_size: + toaddr = self.double_space_size(totalsize) + resizing = True + else: + toaddr = llarena.arena_new_view(self.space) + resizing = False + self.next_collect_after = totalsize finaladdr = self.update_forward_pointers(toaddr) if (self.run_finalizers.non_empty() or self.objects_with_finalizers.non_empty()): @@ -212,10 +223,8 @@ llarena.arena_free(self.space) self.space = toaddr self.free = finaladdr - self.top_of_space = toaddr + self.space_size + self.top_of_space = toaddr + self.next_collect_after self.debug_check_consistency() - if not resizing: - self.record_red_zone() if self.run_finalizers.non_empty(): self.execute_finalizers() self.debug_collect_finish(start_time) @@ -449,13 +458,3 @@ (obj + offset).address[0] = NULL self.objects_with_weakrefs.delete() self.objects_with_weakrefs = new_with_weakref - - def record_red_zone(self): - # XXX KILL ME - free_after_collection = self.top_of_space - self.free - if free_after_collection > self.space_size // 3: - self.red_zone = 0 - else: - self.red_zone += 1 - if free_after_collection < self.space_size // 5: - self.red_zone += 1 From fijal at codespeak.net Mon Oct 20 13:07:20 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 13:07:20 +0200 (CEST) Subject: [pypy-svn] r59258 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020110720.2E200169F7B@codespeak.net> Author: fijal Date: Mon Oct 20 13:07:19 2008 New Revision: 59258 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py Log: move _compile_o_files to base class Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py Mon Oct 20 13:07:19 2008 @@ -24,7 +24,16 @@ args = self._args_for_shared(args) self._execute_c_compiler(cc, args, exe_name) return exe_name - + + def _compile_o_files(self, cfiles, eci, standalone=True): + cfiles = [py.path.local(f) for f in cfiles] + cfiles += [py.path.local(f) for f in eci.separate_module_files] + compile_args = self._compile_args_from_eci(eci, standalone) + ofiles = [] + for cfile in cfiles: + ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) + return ofiles + def gen_makefile(self, cfiles, eci, exe_name=None, path=None): cfiles = [py.path.local(f) for f in cfiles] cfiles += [py.path.local(f) for f in eci.separate_module_files] From fijal at codespeak.net Mon Oct 20 13:26:09 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 13:26:09 +0200 (CEST) Subject: [pypy-svn] r59263 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020112609.AE68C169F6A@codespeak.net> Author: fijal Date: Mon Oct 20 13:26:09 2008 New Revision: 59263 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: fix mac os x Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Mon Oct 20 13:26:09 2008 @@ -113,6 +113,17 @@ return (library_dirs + libraries + self.link_flags + list(eci.link_extra)) + def _finish_linking(self, ofiles, eci, outputfilename, standalone): + if outputfilename is None: + outputfilename = ofiles[0].purebasename + exe_name = py.path.local(os.path.join(str(ofiles[0].dirpath()), + outputfilename)) + if standalone: + exe_name += '.' + self.exe_ext + else: + exe_name += '.' + self.so_ext + return self._link(self.cc, ofiles, self._link_args_from_eci(eci), + standalone, exe_name) # below are some detailed informations for platforms Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Mon Oct 20 13:26:09 2008 @@ -13,21 +13,7 @@ standalone_only = [] shared_only = [] so_ext = 'so' - exe_ext = '' - def _libs(self, libraries): - return ['-l%s' % (lib,) for lib in libraries] - - def _libdirs(self, library_dirs): - return ['-L%s' % (ldir,) for ldir in library_dirs] - - def _includedirs(self, include_dirs): - return ['-I%s' % (idir,) for idir in include_dirs] - - def _preprocess_dirs(self, include_dirs): - # hook for maemo - return include_dirs - def _args_for_shared(self, args): return ['-shared'] + args @@ -39,22 +25,6 @@ for cfile in cfiles: ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) return ofiles - - def compile(self, cfiles, eci, outputfilename=None, standalone=True): - ofiles = self._compile_o_files(cfiles, eci, standalone) - return self._finish_linking(ofiles, eci, outputfilename, standalone) - - def _finish_linking(self, ofiles, eci, outputfilename, standalone): - if outputfilename is None: - outputfilename = ofiles[0].purebasename - exe_name = py.path.local(os.path.join(str(ofiles[0].dirpath()), - outputfilename)) - if standalone: - exe_name += '.' + self.exe_ext - else: - exe_name += '.' + self.so_ext - return self._link(self.cc, ofiles, self._link_args_from_eci(eci), - standalone, exe_name) def gen_makefile(self, cfiles, eci, exe_name=None, path=None): cfiles = [py.path.local(f) for f in cfiles] Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py Mon Oct 20 13:26:09 2008 @@ -2,15 +2,27 @@ """ Base class for all posixish platforms """ -from pypy.translator.platform import Platform +from pypy.translator.platform import Platform, log, _run_subprocess +from pypy.tool import autopath import py class BasePosix(Platform): + exe_ext = '' + def __init__(self, cc=None): if cc is None: cc = 'gcc' self.cc = cc + def _libs(self, libraries): + return ['-l%s' % (lib,) for lib in libraries] + + def _libdirs(self, library_dirs): + return ['-L%s' % (ldir,) for ldir in library_dirs] + + def _includedirs(self, include_dirs): + return ['-I%s' % (idir,) for idir in include_dirs] + def _compile_c_file(self, cc, cfile, compile_args): oname = cfile.new(ext='o') args = ['-c'] + compile_args + [str(cfile), '-o', str(oname)] @@ -34,6 +46,10 @@ ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) return ofiles + def _preprocess_dirs(self, include_dirs): + # hook for maemo + return include_dirs + def gen_makefile(self, cfiles, eci, exe_name=None, path=None): cfiles = [py.path.local(f) for f in cfiles] cfiles += [py.path.local(f) for f in eci.separate_module_files] Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Mon Oct 20 13:26:09 2008 @@ -99,18 +99,6 @@ self._execute_c_compiler(self.link, args, exe_name) return exe_name - def _finish_linking(self, ofiles, eci, outputfilename, standalone): - if outputfilename is None: - outputfilename = ofiles[0].purebasename - exe_name = py.path.local(os.path.join(str(ofiles[0].dirpath()), - outputfilename)) - if standalone: - exe_name += '.' + self.exe_ext - else: - exe_name += '.' + self.so_ext - return self._link(self.cc, ofiles, self._link_args_from_eci(eci), - standalone, exe_name) - def _handle_error(self, returncode, stderr, stdout, outname): if returncode != 0: # Microsoft compilers write compilation errors to stdout From fijal at codespeak.net Mon Oct 20 13:32:51 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 13:32:51 +0200 (CEST) Subject: [pypy-svn] r59264 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020113251.0B928169F21@codespeak.net> Author: fijal Date: Mon Oct 20 13:32:50 2008 New Revision: 59264 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py Log: another missing piece Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py Mon Oct 20 13:32:50 2008 @@ -9,6 +9,8 @@ cflags = ['-O3', '-fomit-frame-pointer'] standalone_only = ['-mdynamic-no-pic'] shared_only = ['-mmacosx-version-min=10.4'] + + so_ext = 'so' def __init__(self, cc=None): if cc is None: Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py Mon Oct 20 13:32:50 2008 @@ -4,7 +4,7 @@ from pypy.translator.platform import Platform, log, _run_subprocess from pypy.tool import autopath -import py +import py, os class BasePosix(Platform): exe_ext = '' From antocuni at codespeak.net Mon Oct 20 13:34:45 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 20 Oct 2008 13:34:45 +0200 (CEST) Subject: [pypy-svn] r59265 - in pypy/branch/oo-jit/pypy/jit/codegen/cli: . test Message-ID: <20081020113445.94ADA169F2C@codespeak.net> Author: antocuni Date: Mon Oct 20 13:34:44 2008 New Revision: 59265 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/methodfactory.py pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py Log: implement correct jumps from a flexswitch case to the parent method. More tests pass Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/methodfactory.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/methodfactory.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/methodfactory.py Mon Oct 20 13:34:44 2008 @@ -58,6 +58,7 @@ def __init__(self, name, res, args): module = assemblyData.module name = '%s_%d' % (name, assemblyData.methcount) + #self.name = name assemblyData.methcount += 1 self.typeBuilder = AutoSaveAssembly.DefineType(module, name) self.meth = AutoSaveAssembly.DefineMethod(self.typeBuilder, @@ -70,7 +71,8 @@ def create_delegate(self, delegatetype, consts): t = self.typeBuilder.CreateType() methinfo = t.GetMethod("invoke") - #assemblyData.auto_save_assembly.Save() +## if self.name == 'generated_case_1': +## assemblyData.auto_save_assembly.Save() return System.Delegate.CreateDelegate(delegatetype, consts, methinfo) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py Mon Oct 20 13:34:44 2008 @@ -132,11 +132,13 @@ gv_retvar.store(self.meth) self.meth.il.Emit(OpCodes.Br, retlabel.il_label) -class ReturnFromFlexSwitch(Operation): - def __init__(self, meth, gv_x): +class JumpFromFlexSwitch(Operation): + + def __init__(self, meth, target, args_gv): self.meth = meth - self.gv_x = gv_x + self.target = target + self.args_gv = args_gv def restype(self): return None @@ -144,11 +146,12 @@ def emit(self): il = self.meth.il graphinfo = self.meth.graphinfo - graphinfo.args_manager.copy_to_inputargs(self.meth, [self.gv_x]) - blockid = graphinfo.graph_retlabel.blockid + graphinfo.args_manager.copy_to_inputargs(self.meth, self.args_gv) + blockid = self.target.blockid il.Emit(OpCodes.Ldc_I4, blockid) il.Emit(OpCodes.Ret) + class Call(Operation): def __init__(self, meth, sigtoken, gv_fnptr, args_gv): Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Mon Oct 20 13:34:44 2008 @@ -313,10 +313,11 @@ class Label(GenLabel): - def __init__(self, blockid, il, inputargs_gv): + def __init__(self, meth, blockid, inputargs_gv): + self.meth = meth self.blockid = blockid - self.il_label = il.DefineLabel() - self.il_trampoline_label = il.DefineLabel() + self.il_label = meth.il.DefineLabel() + self.il_trampoline_label = meth.il.DefineLabel() self.inputargs_gv = inputargs_gv def emit_trampoline(self, meth): @@ -486,7 +487,7 @@ def newblock(self, args_gv): blocks = self.graphinfo.blocks blockid = len(blocks) - result = Label(blockid, self.il, args_gv) + result = Label(self, blockid, args_gv) blocks.append((self, result)) self.graphinfo.args_manager.register(args_gv) return result @@ -626,7 +627,8 @@ return self.linkargs_gv_map.get(gv_var, gv_var) def get_op_Return(self, gv_returnvar): - return ops.ReturnFromFlexSwitch(self, gv_returnvar) + target = self.graphinfo.graph_retlabel + return ops.JumpFromFlexSwitch(self, target, [gv_returnvar]) def emit_code(self): MethodGenerator.emit_code(self) @@ -675,8 +677,14 @@ def finish_and_goto(self, outputargs_gv, label): inputargs_gv = label.inputargs_gv assert len(inputargs_gv) == len(outputargs_gv) - op = ops.FollowLink(self.meth, outputargs_gv, - inputargs_gv, label.il_label) + if self.meth is label.meth: + # jump inside the same method, easy + op = ops.FollowLink(self.meth, outputargs_gv, + inputargs_gv, label.il_label) + else: + # jump from a flexswitch to the parent method + op = ops.JumpFromFlexSwitch(self.meth, label, + outputargs_gv) self.appendop(op) self.close() Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py Mon Oct 20 13:34:44 2008 @@ -10,7 +10,6 @@ def skip(self): py.test.skip('in progress') - test_many_promotions = skip test_two_promotions = skip more_promotes = skip mixed_merges = skip Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py Mon Oct 20 13:34:44 2008 @@ -84,8 +84,6 @@ def test_interior_access(self): py.test.skip('fixme') - def test_switch_goto_parent_block_direct(self): - py.test.skip('fixme') class TestRCliGenopCompile(AbstractRGenOpTestsCompile): RGenOp = RCliGenOp @@ -144,6 +142,3 @@ def test_ovfcheck1_compile(self): py.test.skip('fixme') - - def test_switch_goto_parent_block_compile(self): - py.test.skip('fixme') From witulski at codespeak.net Mon Oct 20 14:51:10 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Mon, 20 Oct 2008 14:51:10 +0200 (CEST) Subject: [pypy-svn] r59266 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081020125110.D66A9169F76@codespeak.net> Author: witulski Date: Mon Oct 20 14:51:08 2008 New Revision: 59266 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: Spilling now used unused Stackpos. The dict used_stack_pos contains all used positions Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Mon Oct 20 14:51:08 2008 @@ -83,7 +83,7 @@ MC_SIZE = 65536 #FIXME: The MemCodeBuild. is not opend in an _open method - def __init__(self, stackdepth, used_registers=[]): + def __init__(self, stackdepth, used_registers=[], used_stack_pos = None): self.stackdepth = stackdepth self.mc = InMemoryCodeBuilder(self.MC_SIZE) #callee-saved registers are commented out @@ -106,7 +106,10 @@ self.known_gv = [] # contains the live genvars (used for spilling and allocation) for reg in used_registers: del self.freeregisters[reg.location.reg] - self.free_stack_pos = {} + if used_stack_pos == None: + self.used_stack_pos = {} + else: + self.used_stack_pos = used_stack_pos def _open(self): pass @@ -290,7 +293,7 @@ def jump(self, gv_condition, args_for_jump_gv): # the targetbuilder must know the registers(live vars) # of the calling block - targetbuilder = Builder(self.stackdepth, args_for_jump_gv) + targetbuilder = Builder(self.stackdepth, args_for_jump_gv, self.used_stack_pos) self.mc.CMP(gv_condition, Immediate32(value)) self.mc.JNE(targetbuilder.mc.tell()) return targetbuilder @@ -439,14 +442,18 @@ if gv_to_spill.location.throw_away: return gv_to_spill else: - #search for free stack position - for i in range(self.stackdepth): - if i in self.free_stack_pos.keys(): - pass - # TODO: move gv_to_spill, stack(i) + #search for free stack position/location + for location in range(self.stackdepth): + if location not in self.used_stack_pos.keys(): + self.mc.MOV(IntVar(Stack64(8*(self.stackdepth-location))), gv_to_spill)#8=scale + self.used_stack_pos[location] = None + new_gv = IntVar(Register64(gv_to_spill.location.reg)) + gv_to_spill.location = Stack64(location) + return new_gv + # no free stack pos + self.used_stack_pos[self.stackdepth] = None # remember as used self.stackdepth = self.stackdepth +1 self.mc.PUSH(gv_to_spill) - self.free_stack_pos[self.stackdepth] = None # remember as used new_gv = IntVar(Register64(gv_to_spill.location.reg)) gv_to_spill.location = Stack64(self.stackdepth) return new_gv @@ -457,8 +464,8 @@ gv_new = self.allocate_register(None, dont_alloc) if a_spilled_gv.location.offset == self.stackdepth: self.mc.POP(gv_new) - del self.free_stack_pos[self.stackdepth] self.stackdepth = self.stackdepth -1 + del self.used_stack_pos[self.stackdepth] assert self.stackdepth >= 0 a_spilled_gv.location = Register64(gv_new.location.reg) self.known_gv.remove(gv_new) @@ -468,9 +475,8 @@ return a_spilled_gv else: # else access the memory - # FIXME: if this genVar becomes the top of stack it will never be pushed self.mc.MOV(gv_new, IntVar(Stack64(8*(self.stackdepth-a_spilled_gv.location.offset))))#8=scale - del self.free_stack_pos[a_spilled_gv.location.offset] + del self.used_stack_pos[a_spilled_gv.location.offset] a_spilled_gv.location = Register64(gv_new.location.reg) self.known_gv.remove(gv_new) return a_spilled_gv @@ -501,7 +507,7 @@ arg_tokens, res_token = sigtoken #print "arg_tokens:",arg_tokens inputargs_gv = [] - builder = Builder(0) # stackdepth = 0 + builder = Builder(0) # stackdepth = 0, no used regs/mem_pos # TODO: Builder._open() entrypoint = builder.mc.tell() # from http://www.x86-64.org/documentation/abi.pdf Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Mon Oct 20 14:51:08 2008 @@ -12,7 +12,8 @@ py.test.skip("not implemented yet") -# pushes/pos some values and than uses a mem access to access the stack +# pushes/pos some values and moves a value into the stack +# always returns 42 def make_mem_func2(rgenop): sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed], lltype.Signed)) builder, gv_mem_func, [gv_x] = rgenop.newgraph(sigtoken, "mem_op") @@ -516,7 +517,6 @@ result = fnptr(42) assert result == 42 - # return def test_memory_access(self): mem_func = make_mem_func(self.RGenOp()) fnptr = self.cast(mem_func,2) @@ -525,6 +525,7 @@ result = fnptr(-1,2) assert result == 5 + # return 42 def test_memory_access2(self): mem_func = make_mem_func2(self.RGenOp()) fnptr = self.cast(mem_func,1) From antocuni at codespeak.net Mon Oct 20 17:56:34 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 20 Oct 2008 17:56:34 +0200 (CEST) Subject: [pypy-svn] r59272 - pypy/branch/oo-jit/pypy/jit/codegen/test Message-ID: <20081020155634.54B4A169FAA@codespeak.net> Author: antocuni Date: Mon Oct 20 17:56:31 2008 New Revision: 59272 Modified: pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py Log: another test failing con cli Modified: pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py Mon Oct 20 17:56:31 2008 @@ -564,6 +564,57 @@ return switch_goto_parent_block_runner +def make_switch_goto_between_flexswitches(T, rgenop): + """ + def f(v0, v1): + if v0 == 1: # switch + if v1 == 2: # switch + return 42 + else: + return 100 + else: + return 200 + """ + sigtoken = rgenop.sigToken(T.FUNC2) + builder, gv_switch, [gv0, gv1] = rgenop.newgraph(sigtoken, "switch") + builder.start_writing() + + const1 = rgenop.genconst(1) + const2 = rgenop.genconst(2) + const42 = rgenop.genconst(42) + const100 = rgenop.genconst(100) + const200 = rgenop.genconst(200) + + flexswitch1, default_builder1 = builder.flexswitch(gv0, [gv1]) + + # outer default branch + default_builder1.finish_and_return(sigtoken, const200) + + # case v0 == 1 + case_builder = flexswitch1.add_case(const1) + flexswitch2, default_builder2 = case_builder.flexswitch(gv1, []) + + # inner default branch + default_builder2.finish_and_return(sigtoken, const100) + + # case v1 == 2 + case_builder = flexswitch2.add_case(const2) + case_builder.finish_and_return(sigtoken, const42) + + builder.end() + return gv_switch + +def get_switch_goto_between_flexswitches_runner(T, RGenOp): + def switch_goto_between_flexswitches_runner(x, y): + rgenop = RGenOp() + gv_switchfn = make_switch_goto_between_flexswitches(T, rgenop) + switchfn = gv_switchfn.revealconst(T.Ptr(T.FUNC2)) + res = switchfn(x, y) + keepalive_until_here(rgenop) # to keep the code blocks alive + return res + return switch_goto_between_flexswitches_runner + + def make_fact(T, rgenop): # def fact(x): # if x: @@ -1241,6 +1292,14 @@ res = fn(42, 16) assert res == 16 + def test_switch_goto_between_flexswitches_compile(self): + fn = self.compile(get_switch_goto_between_flexswitches_runner(self.T, self.RGenOp), [int, int]) + res = fn(1, 2) + assert res == 42 + res = fn(1, 3) + assert res == 100 + res = fn(2, 3) + assert res == 200 def test_fact_compile(self): fn = self.compile(get_fact_runner(self.T, self.RGenOp), [int]) @@ -1495,6 +1554,17 @@ res = fnptr(42, 16) assert res == 16 + def test_switch_goto_between_flexswitches_direct(self): + rgenop = self.RGenOp() + gv_switchfn = make_switch_goto_between_flexswitches(self.T, rgenop) + fnptr = self.cast(gv_switchfn, 2) + res = fnptr(1, 2) + assert res == 42 + res = fnptr(1, 3) + assert res == 100 + res = fnptr(2, 3) + assert res == 200 + def test_large_switch_direct(self): rgenop = self.RGenOp() gv_switchfn = make_large_switch(self.T, rgenop) From fijal at codespeak.net Mon Oct 20 18:06:48 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 18:06:48 +0200 (CEST) Subject: [pypy-svn] r59273 - in pypy/build/benchmem: . testing Message-ID: <20081020160648.73969169F09@codespeak.net> Author: fijal Date: Mon Oct 20 18:06:48 2008 New Revision: 59273 Modified: pypy/build/benchmem/runbench.py pypy/build/benchmem/testing/test_benchtool.py Log: add benchmarks for app profiles Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Mon Oct 20 18:06:48 2008 @@ -20,17 +20,26 @@ class BenchRunner: SEPBENCH = "=" * 80 - def log(self, *args): - print " ".join(map(str, args)) - - -class BenchRunnerBaseSize(BenchRunner): def __init__(self, executable, logpath, options): self.executable = executable self.executable_full_path = py.path.local.sysfind(executable) self.logpath = py.path.local(logpath) self.logstream = self.logpath.open("a") self.options = options + self.tmpdir = py.path.local.make_numbered_dir(prefix="bench") + + def getnames(self): + l = [] + for name, obj in vars(self.benchpath.pyimport()).items(): + if name.startswith("bench") and callable(obj): + l.append(name) + l.sort() + return l + + def log(self, *args): + print " ".join(map(str, args)) + +class BenchRunnerBaseSize(BenchRunner): def write_benchheader(self): print >>self.logstream, self.SEPBENCH @@ -57,12 +66,9 @@ class BenchRunnerBaseTime(BenchRunner): def __init__(self, executable, logpath, options): - self.executable = executable - self.executable_full_path = py.path.local.sysfind(executable) - self.logpath = py.path.local(logpath) - self.logstream = self.logpath.open("a") + BenchRunner.__init__(self, executable, logpath, options) self.numiter = options.basetime_numiter - + def write_benchheader(self): print >>self.logstream, self.SEPBENCH print >>self.logstream, "#benchtype=basetime" @@ -98,13 +104,9 @@ class BenchRunnerObjsize(BenchRunner): def __init__(self, executable, logpath, options): - self.executable = executable + BenchRunner.__init__(self, executable, logpath, options) self.benchpath = benchmarkdir.join("sizes.py") assert self.benchpath.check() - self.logpath = py.path.local(logpath) - self.logstream = self.logpath.open("a") - self.tmpdir = py.path.local.make_numbered_dir(prefix="bench") - self.options = options def makebench(self, name): arglist = str(self.options.numiter) @@ -143,14 +145,6 @@ print >>self.logstream, "#benchargs=%s" %(args,) print >>self.logstream - def getnames(self): - l = [] - for name, obj in vars(self.benchpath.pyimport()).items(): - if name.startswith("bench") and callable(obj): - l.append(name) - l.sort() - return l - def run(self): for name in self.getnames(): self.run_checkpointed(name) @@ -182,6 +176,64 @@ #sys.stdout.write(".") #sys.stdout.flush() +class BenchRunnerAppProfiles(BenchRunner): + ITER2 = 100000 + + def __init__(self, *args): + BenchRunner.__init__(self, *args) + self.benchpath = benchmarkdir.join("appprofiles.py") + + def write_benchheader(self, benchname, args): + print >>self.logstream, self.SEPBENCH + print >>self.logstream, "#benchtype=appprofiles" + print >>self.logstream, "#executable=%s" %(str(self.executable ),) + print >>self.logstream, "#benchpath=%s" %(self.benchpath.basename,) + print >>self.logstream, "#benchname=%s" %(benchname,) + print >>self.logstream, "#benchargs=%s" %(args,) + print >>self.logstream + + def run(self): + for name in self.getnames(): + self.run_once(name) + + def run_once(self, name): + benchpyfile = self.makebench(name) + #self.log("created", benchpyfile) + cmd = "%s -u %s" %(self.executable, benchpyfile) + self.log("running %s(%s)" %(name, self.options.numiter)) + stdout, stdin = os.popen2(cmd) + pid = int(stdin.readline()) + self.write_benchheader(name, self.options.numiter) + rec = smaps.SmapsRecorder(pid, self.logstream) + self.interact_with_child(rec, stdout, stdin) + + def makebench(self, name): + arglist = (int(self.options.numiter)/3000, self.ITER2) + source = py.code.Source(self.benchpath.read(), """ + import gc + def write(c): + sys.stdout.write(c) + sys.stdout.flush() + + if __name__ == "__main__": + import os, sys, gc + pid = os.getpid() + write(str(pid) + "\\n") + %s %s + sys.stdin.close() + """ %(name, arglist)) + p = self.tmpdir.join(self.benchpath.basename) + p.write(source) + return p + + def interact_with_child(self, rec, stdin, stdout): + while not stdin.closed: + try: + rec.snapshot() + except py.error.ENOENT: + break + + # # ================ reading a benchmark log file ======================= # @@ -238,16 +290,9 @@ yield parse_result(stream_iter, kw) def parse_result(stream, kw): - chosen_cls = None - benchtype = kw.pop('benchtype') - for scls in Result.__subclasses__(): - if scls.benchtype == benchtype: - chosen_cls = scls - break - assert chosen_cls is not None, 'Unknown benchtype ' + repr(benchtype) + chosen_cls = benchtype2class[kw.pop('benchtype')] return chosen_cls.parse(stream, kw) - class Result(object): @classmethod def parse(cls, lnstream, kw): @@ -265,9 +310,7 @@ continue return cls(snapshots, **kw) - -class ObjsizeResult(Result): - benchtype = "objsizes" +class CommonResult(Result): def __init__(self, snapshots, executable, benchpath, benchname, benchargs): assert snapshots self.snapshots = snapshots @@ -276,6 +319,9 @@ self.benchname = benchname self.benchargs = benchargs +class ObjsizeResult(CommonResult): + benchtype = "objsizes" + def max(self, attrname): maxvalue = 0 for snap in self.snapshots: @@ -289,6 +335,8 @@ dirty = mapping.private_dirty + mapping.shared_dirty assert mapping.rss == dirty + clean +class AppprofileResult(CommonResult): + benchtype = "appprofiles" class BasesizeResult(Result): benchtype = 'basesize' @@ -297,7 +345,6 @@ assert len(snapshots) == 1 self.executable = executable - class BasetimeResult(Result): benchtype = 'basetime' def __init__(self, timings, executable): @@ -318,6 +365,14 @@ timings.append((name, times)) return cls(timings, **kw) +benchtype2class = {} + +def _update_benchtyp2class(): + for cls in globals().values(): + if Result in getattr(cls, '__mro__', []) and getattr(cls, 'benchtype', None): + benchtype2class[cls.benchtype] = cls + +_update_benchtyp2class() class Mappings(object): HEAP, CODE, DATA = object(), object(), object() @@ -402,11 +457,14 @@ def getrunnerclass(benchtype): if benchtype == "objsizes": return BenchRunnerObjsize - if benchtype == "basesize": + elif benchtype == "basesize": return BenchRunnerBaseSize - if benchtype == "basetime": + elif benchtype == "basetime": return BenchRunnerBaseTime - assert 0,benchtype + elif benchtype == "appprofiles": + return BenchRunnerAppProfiles + else: + raise NotImplementedError("Benchmark type: %s" % (benchtype,)) if __name__ == '__main__': (options, args) = parser.parse_args() Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Mon Oct 20 18:06:48 2008 @@ -37,8 +37,27 @@ names = runner.getnames() assert len(resultset.getname2results()) == len(names) for name, results in resultset.getname2results(): - assert len(results) ==1 - assert len(results[0].snapshots) == 2 + 1 + assert len(results) == 1 + assert len(results[0].snapshots) == 3 + + +def test_apps_runbench_and_read_results(): + tmpdir = py.test.ensuretemp("benchrunner") + benchlog=tmpdir.join("log_apps") + + class options: + numiter = 10 + runner = runbench.BenchRunnerAppProfiles("python2.5", benchlog, options) + assert runner.benchpath.basename == "appprofiles.py" + runner.run() + resultset = runbench.ResultSet() + resultset.parse(benchlog) + + names = runner.getnames() + assert len(resultset.getname2results()) == len(names) + for name, results in resultset.getname2results(): + assert len(results) == 1 + assert len(results[0].snapshots) def test_runbench_functional(): script = py.path.local(runbench.__file__).dirpath("runbench.py") From fijal at codespeak.net Mon Oct 20 18:43:38 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 18:43:38 +0200 (CEST) Subject: [pypy-svn] r59274 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020164338.CAA93169EF4@codespeak.net> Author: fijal Date: Mon Oct 20 18:43:38 2008 New Revision: 59274 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: move _compile_o_files to base class Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py Mon Oct 20 18:43:38 2008 @@ -57,6 +57,15 @@ ofiles = self._compile_o_files(cfiles, eci, standalone) return self._finish_linking(ofiles, eci, outputfilename, standalone) + def _compile_o_files(self, cfiles, eci, standalone=True): + cfiles = [py.path.local(f) for f in cfiles] + cfiles += [py.path.local(f) for f in eci.separate_module_files] + compile_args = self._compile_args_from_eci(eci, standalone) + ofiles = [] + for cfile in cfiles: + ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) + return ofiles + def execute(self, executable, args=None, env=None): returncode, stdout, stderr = _run_subprocess(str(executable), args, env) Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py Mon Oct 20 18:43:38 2008 @@ -37,15 +37,6 @@ self._execute_c_compiler(cc, args, exe_name) return exe_name - def _compile_o_files(self, cfiles, eci, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] - compile_args = self._compile_args_from_eci(eci, standalone) - ofiles = [] - for cfile in cfiles: - ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) - return ofiles - def _preprocess_dirs(self, include_dirs): # hook for maemo return include_dirs Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Mon Oct 20 18:43:38 2008 @@ -82,15 +82,6 @@ self._execute_c_compiler(cc, args, oname) return oname - def _compile_o_files(self, cfiles, eci, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] - compile_args = self._compile_args_from_eci(eci, standalone) - ofiles = [] - for cfile in cfiles: - ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) - return ofiles - def _link(self, cc, ofiles, link_args, standalone, exe_name): args = ['/nologo'] + [str(ofile) for ofile in ofiles] + link_args args += ['/out:%s' % (exe_name,)] From fijal at codespeak.net Mon Oct 20 18:46:38 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 18:46:38 +0200 (CEST) Subject: [pypy-svn] r59275 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020164638.179EF169EF6@codespeak.net> Author: fijal Date: Mon Oct 20 18:46:37 2008 New Revision: 59275 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Log: remove unnecessary stuff Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py Mon Oct 20 18:46:37 2008 @@ -17,82 +17,6 @@ def _args_for_shared(self, args): return ['-shared'] + args - def _compile_o_files(self, cfiles, eci, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] - compile_args = self._compile_args_from_eci(eci, standalone) - ofiles = [] - for cfile in cfiles: - ofiles.append(self._compile_c_file(self.cc, cfile, compile_args)) - return ofiles - - def gen_makefile(self, cfiles, eci, exe_name=None, path=None): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] - - if path is None: - path = cfiles[0].dirpath() - - pypypath = py.path.local(autopath.pypydir) - - if exe_name is None: - exe_name = cfiles[0].new(ext=self.exe_ext) - - m = GnuMakefile(path) - m.exe_name = exe_name - m.eci = eci - - def pypyrel(fpath): - rel = py.path.local(fpath).relto(pypypath) - if rel: - return os.path.join('$(PYPYDIR)', rel) - else: - return fpath - - rel_cfiles = [m.pathrel(cfile) for cfile in cfiles] - rel_ofiles = [rel_cfile[:-2]+'.o' for rel_cfile in rel_cfiles] - m.cfiles = rel_cfiles - - rel_includedirs = [pypyrel(incldir) for incldir in - self._preprocess_dirs(eci.include_dirs)] - - m.comment('automatically generated makefile') - definitions = [ - ('PYPYDIR', autopath.pypydir), - ('TARGET', exe_name.basename), - ('DEFAULT_TARGET', '$(TARGET)'), - ('SOURCES', rel_cfiles), - ('OBJECTS', rel_ofiles), - ('LIBS', self._libs(eci.libraries)), - ('LIBDIRS', self._libdirs(eci.library_dirs)), - ('INCLUDEDIRS', self._includedirs(rel_includedirs)), - ('CFLAGS', self.cflags + list(eci.compile_extra)), - ('LDFLAGS', self.link_flags + list(eci.link_extra)), - ('CC', self.cc) - ] - for args in definitions: - m.definition(*args) - - rules = [ - ('all', '$(DEFAULT_TARGET)', []), - ('$(TARGET)', '$(OBJECTS)', '$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS)'), - ('%.o', '%.c', '$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)'), - ] - - for rule in rules: - m.rule(*rule) - - return m - - def execute_makefile(self, path_to_makefile): - if isinstance(path_to_makefile, GnuMakefile): - path = path_to_makefile.makefile_dir - else: - path = path_to_makefile - log.execute('make in %s' % (path,)) - returncode, stdout, stderr = _run_subprocess('make', ['-C', str(path)]) - self._handle_error(returncode, stdout, stderr, path.join('make')) - def include_dirs_for_libffi(self): return ['/usr/include/libffi'] From arigo at codespeak.net Mon Oct 20 19:04:43 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 20 Oct 2008 19:04:43 +0200 (CEST) Subject: [pypy-svn] r59276 - pypy/trunk/pypy/rpython Message-ID: <20081020170443.C8200169EAD@codespeak.net> Author: arigo Date: Mon Oct 20 19:04:41 2008 New Revision: 59276 Modified: pypy/trunk/pypy/rpython/rlist.py pypy/trunk/pypy/rpython/rstr.py Log: Now that 'contains' can in principle raise, the rtyper needs to call hop.exception_cannot_occur() here and there. Modified: pypy/trunk/pypy/rpython/rlist.py ============================================================================== --- pypy/trunk/pypy/rpython/rlist.py (original) +++ pypy/trunk/pypy/rpython/rlist.py Mon Oct 20 19:04:41 2008 @@ -212,6 +212,7 @@ def rtype_contains((r_lst, _), hop): v_lst, v_any = hop.inputargs(r_lst, r_lst.item_repr) + hop.exception_cannot_occur() return hop.gendirectcall(ll_listcontains, v_lst, v_any, r_lst.get_eqfunc()) class __extend__(pairtype(AbstractBaseListRepr, IntegerRepr)): Modified: pypy/trunk/pypy/rpython/rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/rstr.py (original) +++ pypy/trunk/pypy/rpython/rstr.py Mon Oct 20 19:04:41 2008 @@ -387,6 +387,7 @@ v_end = hop.gendirectcall(r_str1.ll.ll_strlen, v_str1) vres = hop.gendirectcall(r_str1.ll.ll_find, v_str1, v_str2, hop.inputconst(Signed, 0), v_end) + hop.exception_cannot_occur() return hop.genop('int_ne', [vres, hop.inputconst(Signed, -1)], resulttype=Bool) @@ -397,6 +398,7 @@ string_repr = r_str.repr char_repr = r_chr.char_repr v_str, v_chr = hop.inputargs(string_repr, char_repr) + hop.exception_cannot_occur() return hop.gendirectcall(r_str.ll.ll_contains, v_str, v_chr) class __extend__(pairtype(AbstractStringRepr, AbstractTupleRepr)): From xoraxax at codespeak.net Mon Oct 20 19:11:35 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 20 Oct 2008 19:11:35 +0200 (CEST) Subject: [pypy-svn] r59277 - pypy/branch/cbuild-refactor/pypy/translator/tool Message-ID: <20081020171135.A0292169ED9@codespeak.net> Author: xoraxax Date: Mon Oct 20 19:11:35 2008 New Revision: 59277 Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Log: Remove unused globals, cleanup imports. Modified: pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/tool/cbuild.py Mon Oct 20 19:11:35 2008 @@ -1,22 +1,16 @@ -import autopath - import os, sys, inspect, re, imp -from pypy.tool.autopath import pypydir -from pypy.translator.platform import host import py + +from pypy.tool.autopath import pypydir +from pypy.translator.platform import host from pypy.tool.ansi_print import ansi_log -log = py.log.Producer("cbuild") -py.log.setconsumer("cbuild", ansi_log) from pypy.tool.udir import udir -debug = 0 -CFLAGS = os.getenv("CFLAGS") -if CFLAGS: - CFLAGS = CFLAGS.split() -else: - CFLAGS = ['-O3'] +log = py.log.Producer("cbuild") +py.log.setconsumer("cbuild", ansi_log) + class ExternalCompilationInfo(object): From xoraxax at codespeak.net Mon Oct 20 19:13:31 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 20 Oct 2008 19:13:31 +0200 (CEST) Subject: [pypy-svn] r59278 - pypy/branch/cbuild-refactor/pypy/translator/c Message-ID: <20081020171331.9E25C169ED7@codespeak.net> Author: xoraxax Date: Mon Oct 20 19:13:31 2008 New Revision: 59278 Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Log: Removed some windows build related code that was added by amaury in r59191. This should be solved by adding options to the windows platform code. Also the current code requires the user to first compile cpython will all depenencies, run cpython from the build tree to translate rpython programs in order to let the user benefit from these lines. Modified: pypy/branch/cbuild-refactor/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/c/genc.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/c/genc.py Mon Oct 20 19:13:31 2008 @@ -116,23 +116,12 @@ def get_eci(self): from distutils import sysconfig - python_inc = sysconfig.get_python_inc() + python_inc = sysconfig.get_python_inc() # XXX refactor remaining dependencies + # like obmalloc into separately compilable + # modules etc. pypy_include_dir = py.path.local(autopath.pypydir).join('translator', 'c') include_dirs = [python_inc, pypy_include_dir] - library_dirs = [] - - if sys.platform == 'win32': - library_dirs.append(py.path.local(sys.exec_prefix).join('libs')) - - # Append the source distribution include and library directories, - # this allows genc on windows to work in the source tree - include_dirs.append(py.path.local(sys.exec_prefix).join('PC')) - library_dirs.append(py.path.local(sys.executable).dirpath()) - - return ExternalCompilationInfo( - include_dirs=include_dirs, - library_dirs=library_dirs, - ) + return ExternalCompilationInfo(include_dirs=include_dirs) def build_database(self): translator = self.translator From fijal at codespeak.net Mon Oct 20 19:14:00 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 19:14:00 +0200 (CEST) Subject: [pypy-svn] r59279 - pypy/build/benchmem Message-ID: <20081020171400.B5DFB169EEA@codespeak.net> Author: fijal Date: Mon Oct 20 19:14:00 2008 New Revision: 59279 Modified: pypy/build/benchmem/report.py Log: kill gnuplot option for now Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Mon Oct 20 19:14:00 2008 @@ -12,8 +12,6 @@ parser = py.compat.optparse.OptionParser(usage=__doc__) parser.add_option("-l", "--benchlog", action="store", dest="benchlog", default="bench.log", help="logfile to read results from") -parser.add_option("-g", "--gnuplot", action="store_true", dest="gnuplot", default=False, - help="generate gnuplot output") def asciitable(table): colmax = [] @@ -244,9 +242,6 @@ BaseSizeOfInterpreters(resultset).run() BaseTimeOfInterpreters(resultset).run() - if options.gnuplot: - Gnuplot(resultset).run() - #for name, results in reader.name2results.items(): # tw.sep("=", name) # for result in results: From fijal at codespeak.net Mon Oct 20 19:30:44 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 19:30:44 +0200 (CEST) Subject: [pypy-svn] r59280 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020173044.66B95169F18@codespeak.net> Author: fijal Date: Mon Oct 20 19:30:43 2008 New Revision: 59280 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: this hook is not needed on windows Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Mon Oct 20 19:30:43 2008 @@ -131,8 +131,7 @@ rel_ofiles = [rel_cfile[:-2]+'.obj' for rel_cfile in rel_cfiles] m.cfiles = rel_cfiles - rel_includedirs = [pypyrel(incldir) for incldir in - self._preprocess_dirs(eci.include_dirs)] + rel_includedirs = [pypyrel(incldir) for incldir in eci.include_dirs] m.comment('automatically generated makefile') definitions = [ From fijal at codespeak.net Mon Oct 20 19:43:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 20 Oct 2008 19:43:33 +0200 (CEST) Subject: [pypy-svn] r59281 - pypy/build/benchmem/benchmark Message-ID: <20081020174333.4FD5B169F07@codespeak.net> Author: fijal Date: Mon Oct 20 19:43:32 2008 New Revision: 59281 Modified: pypy/build/benchmem/benchmark/appprofiles.py Log: add more allocation patterns Modified: pypy/build/benchmem/benchmark/appprofiles.py ============================================================================== --- pypy/build/benchmem/benchmark/appprofiles.py (original) +++ pypy/build/benchmem/benchmark/appprofiles.py Mon Oct 20 19:43:32 2008 @@ -9,17 +9,34 @@ self.f = float(f) self.next = next +def one(num, first, second): + r = num % 4 + if r == 0: + return newstyle(first, second) + elif r == 1: + return oldstyle(first, second) + elif r == 2: + return (first + 3, second) + elif r == 3: + return [float(first), second] + def bench_allocate_and_throw_away(iter1, iter2): for i in range(iter1): next = None for j in range(iter2): - r = j % 4 - if r == 0: - next = newstyle(j, next) - elif r == 1: - next = oldstyle(j, next) - elif r == 2: - next = (j + 3, next) - elif r == 3: - next = [float(j), next] + next = one(j, j, next) + +def bench_allocate_constant_number(iter1, iter2): + l = [None] * iter1 + for i in range(iter1 * iter2): + l[i % iter1] = one(i, i, i) + +def bench_allocate_couple(iter1, iter2): + alive = [None] * iter2 + for i in range(iter2): + next = None + for j in range(iter1): + next = one(j, j, next) + alive[i] = one(i, i, i) + From afa at codespeak.net Mon Oct 20 21:04:05 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 20 Oct 2008 21:04:05 +0200 (CEST) Subject: [pypy-svn] r59282 - pypy/branch/cbuild-refactor/pypy/translator/platform Message-ID: <20081020190405.A27E6169EDB@codespeak.net> Author: afa Date: Mon Oct 20 21:04:02 2008 New Revision: 59282 Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Log: Fixes for the Windows platform Modified: pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py ============================================================================== --- pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py (original) +++ pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Mon Oct 20 21:04:02 2008 @@ -54,6 +54,8 @@ cflags = ['/MD'] link_flags = [] + standalone_only = [] + shared_only = [] def __init__(self, cc=None): self.cc = 'cl.exe' @@ -63,10 +65,25 @@ self.cflags = ['/MDd', '/Z7'] self.link_flags = ['/debug'] + self.add_cpython_dirs = True + + def _preprocess_dirs(self, include_dirs): + if self.add_cpython_dirs: + return include_dirs + (py.path.local(sys.exec_prefix).join('PC'),) + return include_dirs + + def _includedirs(self, include_dirs): + return ['/I%s' % (idir,) for idir in include_dirs] + def _libs(self, libraries): return ['%s.lib' % (lib,) for lib in libraries] def _libdirs(self, library_dirs): + if self.add_cpython_dirs: + library_dirs = library_dirs + ( + py.path.local(sys.exec_prefix).join('libs'), + py.path.local(sys.executable).dirpath(), + ) return ['/LIBPATH:%s' % (ldir,) for ldir in library_dirs] def _args_for_shared(self, args): @@ -75,7 +92,7 @@ def _link_args_from_eci(self, eci): args = super(Windows, self)._link_args_from_eci(eci) return args + ['/EXPORT:%s' % symbol for symbol in eci.export_symbols] - + def _compile_c_file(self, cc, cfile, compile_args): oname = cfile.new(ext='obj') args = ['/nologo', '/c'] + compile_args + [str(cfile), '/Fo%s' % (oname,)] @@ -102,7 +119,7 @@ if len(stderrlines) > 5: log.ERROR('...') raise CompilationError(stdout, stderr) - + def gen_makefile(self, cfiles, eci, exe_name=None, path=None): cfiles = [py.path.local(f) for f in cfiles] @@ -174,7 +191,7 @@ ['/f', str(path.join('Makefile'))]) finally: oldcwd.chdir() - + self._handle_error(returncode, stdout, stderr, path.join('make')) class NMakefile(posix.GnuMakefile): From fijal at codespeak.net Tue Oct 21 12:19:13 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 21 Oct 2008 12:19:13 +0200 (CEST) Subject: [pypy-svn] r59291 - pypy/build/benchmem/benchmark Message-ID: <20081021101913.AC97A169FD7@codespeak.net> Author: fijal Date: Tue Oct 21 12:19:13 2008 New Revision: 59291 Modified: pypy/build/benchmem/benchmark/appprofiles.py Log: add ability to run it by hand Modified: pypy/build/benchmem/benchmark/appprofiles.py ============================================================================== --- pypy/build/benchmem/benchmark/appprofiles.py (original) +++ pypy/build/benchmem/benchmark/appprofiles.py Tue Oct 21 12:19:13 2008 @@ -39,4 +39,8 @@ next = one(j, j, next) alive[i] = one(i, i, i) - + +if __name__ == '__main__': + bench_allocate_and_throw_away(100000, 3) + bench_allocate_couple(100000, 3) + bench_allocate_constant_number(100000, 3) From fijal at codespeak.net Tue Oct 21 12:19:53 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 21 Oct 2008 12:19:53 +0200 (CEST) Subject: [pypy-svn] r59292 - pypy/build/benchmem Message-ID: <20081021101953.133EB169FD7@codespeak.net> Author: fijal Date: Tue Oct 21 12:19:51 2008 New Revision: 59292 Added: pypy/build/benchmem/report_graphic.py (contents, props changed) Modified: pypy/build/benchmem/runbench.py pypy/build/benchmem/smaps.py Log: * A tool for reporting graphs * A hack that allows to speed up parsing data 3 times, if we want to see only private memory consumption Added: pypy/build/benchmem/report_graphic.py ============================================================================== --- (empty file) +++ pypy/build/benchmem/report_graphic.py Tue Oct 21 12:19:51 2008 @@ -0,0 +1,32 @@ +#!/usr/bin/env python +""" Run: report_graphic [bench_log] +""" + +import sys, py +import smaps, runbench +from pylab import plot, show + +def main(filename): + resultset = runbench.ResultSet() + resultset.parse(py.path.local(filename), True) + # XXX I'm not sure how to determine a number (optparse maybe...) + # right now, just adjust the number below. Also if we want to + # generate postscript or whatever we would need to do this for + # all anyway + name, results = resultset.getname2results()[0] + for result in results: + lgt = len(result.snapshots) + x = [float(i)/lgt for i in range(lgt)] + y = [snapshot.private for snapshot in result.snapshots] + plot(x, y) + show() + +if __name__ == '__main__': + if len(sys.argv) > 3: + print >>sys.stderr, __doc__ + sys.exit(1) + if len(sys.argv) == 2: + name = sys.argv[1] + else: + name = 'bench.log' + main(name) Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Tue Oct 21 12:19:51 2008 @@ -261,9 +261,9 @@ l.append(result) return ResultSet(l) - def parse(self, logpath): + def parse(self, logpath, private_only=False): f = logpath.open() - self.results.extend(self.yield_results(f)) + self.results.extend(self.yield_results(f, private_only)) f.close() def parseheader(self, stream_iter): @@ -275,7 +275,7 @@ key, value = map(str.strip, line[1:].split("=")) kw[key] = value - def yield_results(self, stream): + def yield_results(self, stream, private_only): stream_iter = enumerate(stream) for lineno, line in stream_iter: line = line.rstrip() @@ -287,26 +287,32 @@ kw = self.parseheader(stream_iter) if kw is None: break - yield parse_result(stream_iter, kw) + yield parse_result(stream_iter, kw, private_only) -def parse_result(stream, kw): +def parse_result(stream, kw, private_only): chosen_cls = benchtype2class[kw.pop('benchtype')] - return chosen_cls.parse(stream, kw) + return chosen_cls.parse(stream, kw, private_only) class Result(object): @classmethod - def parse(cls, lnstream, kw): + def parse(cls, lnstream, kw, private_only): snapshots = [] mappings = [] for lineno, line in lnstream: line = line.rstrip() if line == smaps.SmapsRecorder.SEPSNAPSHOT: - snapshots.append(Snapshot(mappings)) + if private_only: + snapshots.append(SimpleSnapshot(mappings)) + else: + snapshots.append(Snapshot(mappings)) mappings = [] elif line == BenchRunner.SEPBENCH: break else: - mappings.append(smaps.Mapping(line)) + if private_only: + mappings.append(smaps.private(line)) + else: + mappings.append(smaps.Mapping(line)) continue return cls(snapshots, **kw) @@ -355,7 +361,7 @@ self.mintimings.append((name, min(timing, key=lambda x: x['real']))) @classmethod - def parse(cls, lnstream, kw): + def parse(cls, lnstream, kw, private_only=False): timings = [] for lineno, line in lnstream: if line.strip() == BenchRunner.SEPBENCH: @@ -416,6 +422,10 @@ def heap_private(self): return self.filter(group=self.HEAP).private +class SimpleSnapshot(object): + def __init__(self, privates): + self.private = sum(privates) + # # ============================================================================== # Option Handling Modified: pypy/build/benchmem/smaps.py ============================================================================== --- pypy/build/benchmem/smaps.py (original) +++ pypy/build/benchmem/smaps.py Tue Oct 21 12:19:51 2008 @@ -1,5 +1,6 @@ import os, sys, re import py +import time class SmapsRecorder: SEPSNAPSHOT = "-"*80 @@ -47,6 +48,11 @@ # # objects gained from reading of the logfile # + +def private(line): + attrs = line.split()[0].split(',') + return int(attrs[4]) + int(attrs[5]) + class Mapping: _attrnames = ("size rss shared_clean shared_dirty " "private_clean private_dirty".split()) From arigo at codespeak.net Tue Oct 21 12:21:04 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 21 Oct 2008 12:21:04 +0200 (CEST) Subject: [pypy-svn] r59293 - in pypy/branch/oo-jit/pypy: jit/hintannotator rpython/lltypesystem rpython/ootypesystem Message-ID: <20081021102104.1704F169FD7@codespeak.net> Author: arigo Date: Tue Oct 21 12:21:02 2008 New Revision: 59293 Modified: pypy/branch/oo-jit/pypy/jit/hintannotator/annotator.py pypy/branch/oo-jit/pypy/jit/hintannotator/model.py pypy/branch/oo-jit/pypy/jit/hintannotator/policy.py pypy/branch/oo-jit/pypy/rpython/lltypesystem/rclass.py pypy/branch/oo-jit/pypy/rpython/ootypesystem/ootype.py Log: Some tweaks to support pyjitpl. I hope I'm not breaking anything... Modified: pypy/branch/oo-jit/pypy/jit/hintannotator/annotator.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/hintannotator/annotator.py (original) +++ pypy/branch/oo-jit/pypy/jit/hintannotator/annotator.py Tue Oct 21 12:21:02 2008 @@ -19,7 +19,9 @@ bookkeeper = HintBookkeeper(self) RPythonAnnotator.__init__(self, translator, policy=policy, bookkeeper=bookkeeper) - self.exceptiontransformer = base_translator.getexceptiontransformer() + if policy.exceptiontransform: + etrafo = base_translator.getexceptiontransformer() + self.exceptiontransformer = etrafo def build_types(self, origgraph, input_args_hs): desc = self.bookkeeper.getdesc(origgraph) Modified: pypy/branch/oo-jit/pypy/jit/hintannotator/model.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/hintannotator/model.py (original) +++ pypy/branch/oo-jit/pypy/jit/hintannotator/model.py Tue Oct 21 12:21:02 2008 @@ -381,6 +381,9 @@ return SomeLLAbstractConstant(lltype.Bool, {}) def getfield(hs_v1, hs_fieldname): + hs_res = handle_getfield_typeptr(hs_v1, hs_fieldname) + if hs_res is not None: + return hs_res S = hs_v1.concretetype.TO FIELD_TYPE = getattr(S, hs_fieldname.const) return variableoftype(FIELD_TYPE, hs_v1.deepfrozen, cause=hs_v1) @@ -558,6 +561,9 @@ return hs_f1._call_single_graph(fnobj.graph, lltype.typeOf(fnobj).RESULT, *args_hs) def getfield(hs_c1, hs_fieldname): + hs_res = handle_getfield_typeptr(hs_c1, hs_fieldname) + if hs_res is not None: + return hs_res S = hs_c1.concretetype.TO FIELD_TYPE = getattr(S, hs_fieldname.const) return hs_c1.getfield_impl(S, FIELD_TYPE) @@ -851,6 +857,17 @@ cause="non-pure residual call to %s" % graph) return h_res +def handle_getfield_typeptr(hs_struct, hs_fieldname): + if hs_fieldname.const == 'typeptr': + S = originalconcretetype(hs_struct).TO + if S._hints.get('typeptr'): + bookkeeper = getbookkeeper() + if bookkeeper.annotator.policy.pyjitpl: + RESTYPE = getattr(S, 'typeptr') + hs_concrete = SomeLLAbstractConstant(RESTYPE, {}) + return hs_concrete + return None + # ____________________________________________________________ # # Register automatically simple operations Modified: pypy/branch/oo-jit/pypy/jit/hintannotator/policy.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/hintannotator/policy.py (original) +++ pypy/branch/oo-jit/pypy/jit/hintannotator/policy.py Tue Oct 21 12:21:02 2008 @@ -8,19 +8,13 @@ oopspec = False entrypoint_returns_red = True hotpath = False + pyjitpl = False + exceptiontransform = True - def __init__(self, novirtualcontainer = None, - oopspec = None, - entrypoint_returns_red = None, - hotpath = None): - if novirtualcontainer is not None: - self.novirtualcontainer = novirtualcontainer - if oopspec is not None: - self.oopspec = oopspec - if entrypoint_returns_red is not None: - self.entrypoint_returns_red = entrypoint_returns_red - if hotpath is not None: - self.hotpath = hotpath + def __init__(self, **kwds): + for key, value in kwds.items(): + assert hasattr(self, key), "no such option: %r" % (key,) + setattr(self, key, value) def copy(self, **kwds): new = instantiate(self.__class__) Modified: pypy/branch/oo-jit/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/branch/oo-jit/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/branch/oo-jit/pypy/rpython/lltypesystem/rclass.py Tue Oct 21 12:21:02 2008 @@ -58,7 +58,8 @@ OBJECT_VTABLE = lltype.ForwardReference() CLASSTYPE = Ptr(OBJECT_VTABLE) OBJECT = GcStruct('object', ('typeptr', CLASSTYPE), - hints = {'immutable': True, 'shouldntbenull': True}) + hints = {'immutable': True, 'shouldntbenull': True, + 'typeptr': True}) OBJECTPTR = Ptr(OBJECT) OBJECT_VTABLE.become(Struct('object_vtable', #('parenttypeptr', CLASSTYPE), Modified: pypy/branch/oo-jit/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/branch/oo-jit/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/branch/oo-jit/pypy/rpython/ootypesystem/ootype.py Tue Oct 21 12:21:02 2008 @@ -393,6 +393,7 @@ class AbstractString(BuiltinADTType): + oopspec_name = 'str' immutable = True def __init__(self): From fijal at codespeak.net Tue Oct 21 13:18:47 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 21 Oct 2008 13:18:47 +0200 (CEST) Subject: [pypy-svn] r59296 - in pypy/build/benchmem: . benchmark Message-ID: <20081021111847.600ED16A0A3@codespeak.net> Author: fijal Date: Tue Oct 21 13:18:46 2008 New Revision: 59296 Modified: pypy/build/benchmem/benchmark/appprofiles.py pypy/build/benchmem/report_graphic.py pypy/build/benchmem/runbench.py Log: * Some adaptations of numbers, to actually showcase what we're after * Add a very nasty cycle based benchmark * Show all graphs by default Modified: pypy/build/benchmem/benchmark/appprofiles.py ============================================================================== --- pypy/build/benchmem/benchmark/appprofiles.py (original) +++ pypy/build/benchmem/benchmark/appprofiles.py Tue Oct 21 13:18:46 2008 @@ -21,15 +21,15 @@ return [float(first), second] def bench_allocate_and_throw_away(iter1, iter2): - for i in range(iter1): + for i in range(iter2): next = None - for j in range(iter2): + for j in range(iter1): next = one(j, j, next) def bench_allocate_constant_number(iter1, iter2): - l = [None] * iter1 + l = [None] * iter2 for i in range(iter1 * iter2): - l[i % iter1] = one(i, i, i) + l[i % iter2] = one(i, i, i) def bench_allocate_couple(iter1, iter2): alive = [None] * iter2 @@ -39,8 +39,34 @@ next = one(j, j, next) alive[i] = one(i, i, i) +def bench_cpython_nasty(iter1, iter2): + # we create some cycles here, to expose cpython's dealing + # with reference cycles + def create_cycle(): + class A(object): + def __init__(self, prev, next): + self.prev = prev + self.next = next + + a1 = A(None, None) + a2 = A(a1, None) + a3 = A(a2, a1) + a2.next = a3 + a1.next = a2 + a1.prev = a3 + + class B(object): + def __init__(self, next): + self.next = next + self.cycle = create_cycle() + + for i in range(iter2): + next = None + for i in range(iter1/3): + next = B(next) if __name__ == '__main__': - bench_allocate_and_throw_away(100000, 3) - bench_allocate_couple(100000, 3) - bench_allocate_constant_number(100000, 3) + bench_allocate_and_throw_away(10000, 3) + bench_allocate_couple(10000, 3) + bench_allocate_constant_number(10000, 3) + bench_cpython_nasty(10000, 3) Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Tue Oct 21 13:18:46 2008 @@ -13,13 +13,13 @@ # right now, just adjust the number below. Also if we want to # generate postscript or whatever we would need to do this for # all anyway - name, results = resultset.getname2results()[0] - for result in results: - lgt = len(result.snapshots) - x = [float(i)/lgt for i in range(lgt)] - y = [snapshot.private for snapshot in result.snapshots] - plot(x, y) - show() + for name, results in resultset.getname2results(): + for result in results: + lgt = len(result.snapshots) + x = [float(i)/lgt for i in range(lgt)] + y = [snapshot.private for snapshot in result.snapshots] + plot(x, y) + show() if __name__ == '__main__': if len(sys.argv) > 3: Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Tue Oct 21 13:18:46 2008 @@ -177,7 +177,7 @@ #sys.stdout.flush() class BenchRunnerAppProfiles(BenchRunner): - ITER2 = 100000 + ITER2 = 10 def __init__(self, *args): BenchRunner.__init__(self, *args) @@ -208,7 +208,7 @@ self.interact_with_child(rec, stdout, stdin) def makebench(self, name): - arglist = (int(self.options.numiter)/3000, self.ITER2) + arglist = (int(self.options.numiter), self.ITER2) source = py.code.Source(self.benchpath.read(), """ import gc def write(c): From fijal at codespeak.net Tue Oct 21 13:19:19 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 21 Oct 2008 13:19:19 +0200 (CEST) Subject: [pypy-svn] r59297 - pypy/build/benchmem Message-ID: <20081021111919.3612416A0A9@codespeak.net> Author: fijal Date: Tue Oct 21 13:19:18 2008 New Revision: 59297 Modified: pypy/build/benchmem/report_graphic.py Log: adapt comment Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Tue Oct 21 13:19:18 2008 @@ -9,10 +9,7 @@ def main(filename): resultset = runbench.ResultSet() resultset.parse(py.path.local(filename), True) - # XXX I'm not sure how to determine a number (optparse maybe...) - # right now, just adjust the number below. Also if we want to - # generate postscript or whatever we would need to do this for - # all anyway + # by default it shows all graphs, a bit boring, but educating ;) for name, results in resultset.getname2results(): for result in results: lgt = len(result.snapshots) From witulski at codespeak.net Tue Oct 21 13:39:19 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Tue, 21 Oct 2008 13:39:19 +0200 (CEST) Subject: [pypy-svn] r59299 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081021113919.3A08616A030@codespeak.net> Author: witulski Date: Tue Oct 21 13:39:18 2008 New Revision: 59299 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: *Stack scale calculation is now done in the assebler. *compute moves (mapping of gv from one block to an other) now uses location objects insted of strings *the mapping of gv is now correct(remember locations befor the call and restore them in start_writing Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Tue Oct 21 13:39:18 2008 @@ -59,7 +59,7 @@ self.write_modRM_byte(mod, modrm1, modrm2) # no scale(has no effect on rsp), no index, base = rsp self.write_SIB(0, 4, 4) - self.writeImm32(arg1.location.offset) + self.writeImm32(8*arg1.location.offset) #8 == scale return quadreg_instr # exchange the two arguments (modrm2/modrm1) @@ -94,7 +94,7 @@ self.write_modRM_byte(mod, modrm1, modrm2) # no scale(has no effect on rsp), no index, base = rsp self.write_SIB(0, 4, 4) - self.writeImm32(arg2.location.offset) + self.writeImm32(8*arg2.location.offset) #8==scale return quadreg_instr @@ -213,7 +213,7 @@ _MOV_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, None, "\xC7", 3, None, 0) _MOV_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x89", 3, None, None) _MOV_QWREG_IMM64 = make_two_operand_instr_with_alternate_encoding(1,0,0,None,"B8",None,None) - _MOV_QWREG_STACK = make_two_operand_instr( 1, 0, 0, None, "\x8B", 2, None, 4)#4 =RSP + _MOV_QWREG_STACK = make_two_operand_instr( 1, 0, 0, None, "\x8B", 2, None, 4)#4==RSP _MOV_STACK_QWREG = make_two_operand_instr( 1, 0, 0, None, "\x89", 2, None, 4) _IDIV_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xF7", 3, None, 7) @@ -252,7 +252,7 @@ _XOR_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, None, "\x81", 3, None, 6) _XOR_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x31", 3, None, None) - # TODO: maybe a problem with more ore less than two arg. + # TODO(all ops): maybe a problem with more ore less than two arg. def ADD(self, op1, op2): method = getattr(self, "_ADD"+op1.to_string()+op2.to_string()) method(op1, op2) @@ -296,6 +296,7 @@ method(op1) # 4 length of the immediate + # want_jump_to is an 32bit(!) adress def JMP(self,want_jump_to): #method = getattr(self, "_JMP"+op1.to_string()) #method(want_jump_to) @@ -313,7 +314,7 @@ method = getattr(self, "_OR"+op1.to_string()+op2.to_string()) method(op1, op2) - #FIXME: "POP/PUSH NONE" BUG + #FIXME: "POP/PUSH NONE" BUG- (maybe fixed) def POP(self, op1): method = getattr(self, "_POP"+op1.to_string()) method(op1) @@ -396,9 +397,7 @@ if x[0]=='-': # parse to string and cut "0x" off # fill with Fs if to short - #print "x before:",x x = self.cast_neg_hex32(int(x,16)) - #print "x after:",x y = "F"*(8-len(x))+x[0:len(x)] else: # parse to string and cut "0x" off Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Tue Oct 21 13:39:18 2008 @@ -2,7 +2,6 @@ from pypy.rlib.objectmodel import specialize from pypy.jit.codegen.x86_64.objmodel import IntVar, Register64, Register8, Immediate8, Immediate32, Immediate64, Stack64 from pypy.jit.codegen.x86_64.codebuf import InMemoryCodeBuilder -#TODO: understand llTypesystem from pypy.rpython.lltypesystem import llmemory, lltype from pypy.jit.codegen.ia32.objmodel import LL_TO_GENVAR from pypy.jit.codegen.model import GenLabel @@ -82,7 +81,6 @@ MC_SIZE = 65536 - #FIXME: The MemCodeBuild. is not opend in an _open method def __init__(self, stackdepth, used_registers=[], used_stack_pos = None): self.stackdepth = stackdepth self.mc = InMemoryCodeBuilder(self.MC_SIZE) @@ -103,9 +101,12 @@ # "r14":None, # "r15":None, } + self._orig_location={} self.known_gv = [] # contains the live genvars (used for spilling and allocation) for reg in used_registers: del self.freeregisters[reg.location.reg] + self._orig_location[reg] = reg.location + self.known_gv.append(reg) if used_stack_pos == None: self.used_stack_pos = {} else: @@ -176,6 +177,7 @@ registers[i] = self.move_back_to_register(registers[i], dont_alloc) dont_alloc.append(registers[i].location.reg) # some operations dont suppoert immediateoperands + # but only registers if move_imm_too and isinstance(registers[i], Immediate32): gv_new = self.allocate_register(None, dont_alloc) self.mc.MOV(gv_new, registers[i]) @@ -267,21 +269,26 @@ self.mc.SETGE(IntVar(Register8("al"))) return gv_z + # move back the gv to orig. positions + # (this pos. could be changed here which + # could result in wrong locations of the gv) + def start_writing(self): + for i in range(len(self.known_gv)): + if self.known_gv[i] in self._orig_location: + self.known_gv[i].location = self._orig_location[self.known_gv[i]] + # the moves to pass arg. when making a jump to a block # the targetvars are only copys - # FIXME: problem with mapping of stackpositions def _compute_moves(self, outputargs_gv, targetargs_gv): tar2src = {} tar2loc = {} - src2loc = {} + src2loc = {} for i in range(len(outputargs_gv)): - target_gv = targetargs_gv[i].location.reg - source_gv = outputargs_gv[i].location.reg - tar2src[target_gv] = source_gv - tar2loc[target_gv] = target_gv - src2loc[source_gv] = source_gv + tar2src[targetargs_gv[i].location] = outputargs_gv[i].location + tar2loc[targetargs_gv[i].location] = targetargs_gv[i].location + src2loc[outputargs_gv[i].location] = outputargs_gv[i].location movegen = MoveEmitter(self) - emit_moves(movegen, [target_gv.location.reg for target_gv in targetargs_gv], + emit_moves(movegen, [target_gv.location for target_gv in targetargs_gv], tar2src, tar2loc, src2loc) return movegen.moves @@ -302,7 +309,9 @@ jump_if_false = _new_jump("jump_if_false", 1) jump_if_true = _new_jump('jump_if_true', 0) - # TODO: move stackpointer + # moves stackpointer if there are + # gv on the stack which are not + # need anymore def finish_and_return(self, sigtoken, gv_returnvar): #self.mc.write("\xB8\x0F\x00\x00\x00") self._open() @@ -311,31 +320,32 @@ # throw them away if not self.stackdepth == 0: self.mc.ADD(IntVar(Register64("rsp")), Immediate32(self.stackdepth*8)) + self.stackdepth == 0 if not gv_returnvar == None:#check void return self.mc.MOV(gv_return, gv_returnvar) self.mc.RET() self._close() - #assert self.stackdepth == 0 # FIXME: uses 32bit displ # TODO: return also stackdepth or pop! # if the label is greater than 32bit # it must be in a register (not supported) def finish_and_goto(self, outputargs_gv, target): - #import pdb;pdb.set_trace() self._open() #gv_x = self.allocate_register() #self.mc.MOV(gv_x,Immediate64(target.startaddr)) - #self.mc.JMP(gv_x) + #self.mc.JMP(gv_x) moves = self._compute_moves(outputargs_gv, target.arg_positions) for source_gv, target_gv in moves: - self.mc.MOV(IntVar(Register64(source_gv)),IntVar(Register64(target_gv))) + # TODO: check for MOV(STACK,STACK) + self.mc.MOV(IntVar(source_gv), IntVar(target_gv)) self.mc.JMP(target.startaddr) self._close() # FIXME: returns only IntVars # TODO: support the allocation of 8bit Reg - # TODO: (Optimization)Don't remember genVars which contain konstants + # Don't remember genVars which contain constants(Optimization) + # An allocation could have spilling as sideeffect(stack mov) def allocate_register(self, register=None, dontalloc = None): if dontalloc is None: dontalloc = [] @@ -397,7 +407,7 @@ def end(self): pass - # TODO: args_gv muste be a list of unique GenVars + # TODO: args_gv muste be a list of unique GenVars, dont searchs for double gv # Spilling could change the location of a # genVar after this Label. That will result in a # wrong mapping in _compute_moves when leaving this block. @@ -410,17 +420,21 @@ gv_x = self.allocate_register() self.mc.MOV(gv_x, args_gv[i]) args_gv[i] = gv_x - # copy the gv + # copy the genvars: + # without copying the references could be changed + # which can result in wrong locations of the gv copy_args.append(IntVar(Register64(args_gv[i].location.reg))) L = Label(self.mc.tell(), copy_args, 0) return L def _close(self): - self.mc.done() + self.mc.done() # used for dump code (debugging) # TODO: alloc strategy # TODO: support 8bit reg. alloc - # just greddy spilling + # just greedy spilling. + # moves GenVar locations on the stack + # to free an register def spill_register(self, dont_spill=None): if dont_spill is None: dont_spill = [] @@ -438,19 +452,21 @@ raise WrongArgException("to many dont_spill/dont_alloc registers") assert isinstance(gv_to_spill.location, Register64) # if the register contains a genCons - # it has not to be saved + # it has not to be saved on the stack if gv_to_spill.location.throw_away: return gv_to_spill else: - #search for free stack position/location + # search for free stack position/location for location in range(self.stackdepth): if location not in self.used_stack_pos.keys(): - self.mc.MOV(IntVar(Stack64(8*(self.stackdepth-location))), gv_to_spill)#8=scale + # a location has been found which is not the tos. + self.mc.MOV(IntVar(Stack64(self.stackdepth-location)), gv_to_spill) self.used_stack_pos[location] = None new_gv = IntVar(Register64(gv_to_spill.location.reg)) gv_to_spill.location = Stack64(location) return new_gv - # no free stack pos + # no free stack pos found + # use the top of stack ->push self.used_stack_pos[self.stackdepth] = None # remember as used self.stackdepth = self.stackdepth +1 self.mc.PUSH(gv_to_spill) @@ -458,7 +474,9 @@ gv_to_spill.location = Stack64(self.stackdepth) return new_gv - # FIXME: pushed values are not allways poped (if not TOS) + # A GenVar which location is on the stack + # will be moved back to make operations posible + # and faster def move_back_to_register(self, a_spilled_gv, dont_alloc): # if a_spilled_gv is the top of stack gv_new = self.allocate_register(None, dont_alloc) @@ -475,7 +493,7 @@ return a_spilled_gv else: # else access the memory - self.mc.MOV(gv_new, IntVar(Stack64(8*(self.stackdepth-a_spilled_gv.location.offset))))#8=scale + self.mc.MOV(gv_new, IntVar(Stack64(self.stackdepth-a_spilled_gv.location.offset))) del self.used_stack_pos[a_spilled_gv.location.offset] a_spilled_gv.location = Register64(gv_new.location.reg) self.known_gv.remove(gv_new) @@ -505,7 +523,6 @@ def newgraph(self, sigtoken, name): arg_tokens, res_token = sigtoken - #print "arg_tokens:",arg_tokens inputargs_gv = [] builder = Builder(0) # stackdepth = 0, no used regs/mem_pos # TODO: Builder._open() Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Tue Oct 21 13:39:18 2008 @@ -21,7 +21,7 @@ builder.genop1("int_push", gv_x) builder.genop1("int_push", gv_x) builder.mc.MOV(gv_x, rgenop.genconst(42)) - builder.mc.MOV(IntVar(Stack64(8)), gv_x) + builder.mc.MOV(IntVar(Stack64(1)), gv_x) builder.genop1("int_pop", gv_x) builder.genop1("int_pop", gv_x) builder.finish_and_return(sigtoken, gv_x) @@ -39,7 +39,7 @@ builder.genop1("int_push", gv_y) builder.genop1("int_inc", gv_y) builder.genop1("int_push", gv_y) - builder.mc.MOV(gv_x, IntVar(Stack64(8))) # rsp+8(bytes) (stack position of the first push) + builder.mc.MOV(gv_x, IntVar(Stack64(1))) # rsp+1 (stack position of the first push) builder.genop1("int_pop", gv_y) builder.genop1("int_pop", gv_y) builder.finish_and_return(sigtoken, gv_x) From witulski at codespeak.net Tue Oct 21 14:22:54 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Tue, 21 Oct 2008 14:22:54 +0200 (CEST) Subject: [pypy-svn] r59300 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081021122254.2B58916A10D@codespeak.net> Author: witulski Date: Tue Oct 21 14:22:53 2008 New Revision: 59300 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: Added is_true and same_as + test (+ litle cleanup) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py Tue Oct 21 14:22:53 2008 @@ -40,6 +40,7 @@ class IntVar(model.GenVar): def __init__(self, location): self.location = location + self.is_const = False assert isinstance(location, Location) def to_string(self): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Tue Oct 21 14:22:53 2008 @@ -138,6 +138,20 @@ op_int_sub = make_two_argument_method("SUB") # TODO: use DEC op_int_xor = make_two_argument_method("XOR") + # must return a genvar + def genop_same_as(self, imm): + gv_x = self.allocate_register() + self.mc.MOV(gv_x, imm) + return gv_x + + def op_int_is_true(self, gv_x): + [gv_x, gv_y] = self.move_to_registers([gv_x, Immediate32(1)], None, move_imm_too=True) + self.mc.CMP(gv_x, gv_y) + [gv_x, gv_y] = self.throw_away_if_const([gv_x,gv_y]) + gv_z = self.allocate_register("rax") + self.mc.SETE(IntVar(Register8("al"))) + return gv_z + # TODO: support reg8 def op_cast_bool_to_int(self, gv_x): [gv_x] = self.move_to_registers([gv_x]) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Tue Oct 21 14:22:53 2008 @@ -531,6 +531,16 @@ fnptr = self.cast(mem_func,1) result = fnptr(0) assert result == 42 + + def test_is_true(self): + test_function = make_one_op_instr(self.RGenOp(),"int_is_true") + fnptr = self.cast(test_function,1) + result = fnptr(1) + assert result == 1 + result = fnptr(0) + assert result == 0 + result = fnptr(42) + assert result == 0 # def test_invert(self): @@ -544,23 +554,17 @@ test_switch_many_args_direct = skip test_directtesthelper_direct = skip - test_dummy_compile = skip test_cast_raising = skip test_float_adder = skip test_float_call = skip test_float_loop_direct = skip - test_dummy_direct = skip test_largedummy_direct = skip test_switch_direct = skip test_large_switch_direct = skip test_fact_direct = skip test_calling_pause_direct = skip - test_longwinded_and_direct = skip test_condition_result_cross_link_direct = skip - #test_flipped_cmp_with_immediate = skip test_jump_to_block_with_many_vars = skip - test_same_as = skip - test_pause_and_resume_direct = skip test_like_residual_red_call_with_exc_direct = skip test_call_functions_with_different_signatures_direct = skip test_defaultonly_switch = skip @@ -589,5 +593,4 @@ test_fieldaccess = skip test_interior_access = skip test_interior_access_float = skip - test_demo_f1_direct = skip - test_red_switch = skip \ No newline at end of file + test_demo_f1_direct = skip \ No newline at end of file From antocuni at codespeak.net Tue Oct 21 16:28:27 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 21 Oct 2008 16:28:27 +0200 (CEST) Subject: [pypy-svn] r59301 - in pypy/branch/oo-jit/pypy/jit/codegen/cli: . test Message-ID: <20081021142827.4B95D169F61@codespeak.net> Author: antocuni Date: Tue Oct 21 16:28:25 2008 New Revision: 59301 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py Log: (IN-PROGRESS) a bit of refactoring and renaming while thinking how to fully support jumps between methods Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py Tue Oct 21 16:28:25 2008 @@ -147,8 +147,9 @@ il = self.meth.il graphinfo = self.meth.graphinfo graphinfo.args_manager.copy_to_inputargs(self.meth, self.args_gv) - blockid = self.target.blockid - il.Emit(OpCodes.Ldc_I4, blockid) + block_id = self.target.block_id + #import pdb;pdb.set_trace() + il.Emit(OpCodes.Ldc_I4, block_id) il.Emit(OpCodes.Ret) @@ -312,8 +313,13 @@ self.gv_exitswitch.load(graph) graph.gv_inputargs.load(graph) il.Emit(OpCodes.Callvirt, meth_execute) - il.Emit(OpCodes.Stloc, graph.jumpto_var) - il.Emit(OpCodes.Br, graph.il_dispatch_jump_label) + if graph.jumpto_var is None: + # we are inside a nested flexswitch, just return to parent + il.Emit(OpCodes.Ret) + else: + # we are in the main method, do the dispatching + il.Emit(OpCodes.Stloc, graph.jumpto_var) + il.Emit(OpCodes.Br, graph.il_dispatch_jump_label) class WriteLine(Operation): Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Tue Oct 21 16:28:25 2008 @@ -313,9 +313,9 @@ class Label(GenLabel): - def __init__(self, meth, blockid, inputargs_gv): + def __init__(self, meth, block_id, inputargs_gv): self.meth = meth - self.blockid = blockid + self.block_id = block_id self.il_label = meth.il.DefineLabel() self.il_trampoline_label = meth.il.DefineLabel() self.inputargs_gv = inputargs_gv @@ -427,7 +427,7 @@ arglist = [class2type(cls) for cls in sigtoken.args] restype = class2type(sigtoken.res) delegatetype = class2type(sigtoken.funcclass) - graph = GraphGenerator(self, name, restype, arglist, + graph = MainMethod(self, name, restype, arglist, delegatetype) builder = graph.branches[0] return builder, graph.gv_entrypoint, graph.inputargs_gv[:] @@ -436,15 +436,40 @@ return ReplayBuilder(self), [dummy_var] * len(label.inputargs_gv) +""" +Glossary: + + - Graph: a RPython graph + + - Method: a .NET method + + - in case of flexswitches, a graph is composed by many methods + + - each method is a collections of blocks + + - MainMethod: the method containing the first block of the graph, and all + the blocks reachable without passing throgh a flexswitch + + - CaseMethod: a method containing the blocks for a specific case of a + flexswitch + + - method_id: unique 16 bit number that identifies a method (either MainMethod or + CaseMethod) inside a graph. MainMethod.method_id == 0 + + - block_num: unique 16 bit number that identifies a block inside a method + + - block_id: unique 32 bit number that identifies a block inside a graph; it + is computed as (method_id << 16 | block_num) +""" + class GraphInfo: - def __init__(self): - self.has_flexswitches = False - self.blocks = [] # blockid -> (meth, label) - self.flexswitch_meths = [] - self.main_retlabel = None + def __init__(self): + #self.blocks = [] # block_id -> (meth, label) self.args_manager = ArgsManager() class MethodGenerator: + + method_id = -1 # must be overridden def __init__(self, rgenop, name, restype, arglist, delegatetype, graphinfo): @@ -465,6 +490,7 @@ self.genconsts = {} self.branches = [] self.newbranch() + self.blocks = [] # block_num -> label if restype is None: self.gv_retvar = None self.retlabel = self.newblock([]) @@ -485,12 +511,19 @@ return branch def newblock(self, args_gv): - blocks = self.graphinfo.blocks - blockid = len(blocks) - result = Label(self, blockid, args_gv) - blocks.append((self, result)) +## blocks = self.graphinfo.blocks +## block_id = len(blocks) +## result = Label(self, block_id, args_gv) +## blocks.append((self, result)) + + block_num = len(self.blocks) + assert block_num < 2**16 + assert self.method_id >= 0 + block_id = self.method_id << 16 | block_num + lbl = Label(self, block_id, args_gv) + self.blocks.append(lbl) self.graphinfo.args_manager.register(args_gv) - return result + return lbl def newlocalvar(self, clitype): return GenLocalVar(self, self.il.DeclareLocal(clitype)) @@ -543,25 +576,32 @@ def emit_before_returnblock(self): pass + def setup_dispatch_block(self): + self.il_dispatch_jump_label = self.il.DefineLabel() + self.jumpto_var = self.il.DeclareLocal(class2type(cInt32)) + -class GraphGenerator(MethodGenerator): +class MainMethod(MethodGenerator): + + method_id = 0 + def __init__(self, rgenop, name, restype, args, delegatetype): graphinfo = GraphInfo() MethodGenerator.__init__(self, rgenop, name, restype, args, delegatetype, graphinfo) graphinfo.graph_retlabel = self.retlabel + self.has_flexswitches = False def setup_flexswitches(self): - if self.graphinfo.has_flexswitches: + if self.has_flexswitches: return - self.graphinfo.has_flexswitches = True - self.il_dispatch_jump_label = self.il.DefineLabel() - self.jumpto_var = self.il.DeclareLocal(class2type(cInt32)) + self.has_flexswitches = True + self.setup_dispatch_block() def get_op_Return(self, gv_returnvar): return ops.Return(self, gv_returnvar) def emit_preamble(self): - if not self.graphinfo.has_flexswitches: + if not self.has_flexswitches: return # compute the shape of InputArgs @@ -576,23 +616,23 @@ self.gv_inputargs.store(self) def emit_before_returnblock(self): - if not self.graphinfo.has_flexswitches: + if not self.has_flexswitches: return # make sure we don't enter dispatch_jump by mistake self.il.Emit(OpCodes.Br, self.retlabel.il_label) self.il.MarkLabel(self.il_dispatch_jump_label) - blocks = self.graphinfo.blocks + blocks = self.blocks il_labels = new_array(System.Reflection.Emit.Label, len(blocks)) - for blockid in range(len(blocks)): - builder, label = blocks[blockid] - if builder is not self: - continue # XXX FIXME - il_labels[blockid] = label.il_trampoline_label + for block_num in range(len(blocks)): + label = blocks[block_num] + il_labels[block_num] = label.il_trampoline_label + # XXX: call the right case if no block was found + #print 'Emitting dispatch switch' self.il.Emit(OpCodes.Ldloc, self.jumpto_var) self.il.Emit(OpCodes.Switch, il_labels) - # XXX: handle blockids that are inside flexswitch cases + # XXX: handle block_ids that are inside flexswitch cases # default: Utils.throwInvalidBlockId(jumpto) clitype = class2type(cUtils) meth = clitype.GetMethod("throwInvalidBlockId") @@ -600,17 +640,18 @@ self.il.Emit(OpCodes.Call, meth) # emit all the trampolines to the blocks - for builder, label in blocks: - if builder is not self: - continue #XXX? + for label in blocks: label.emit_trampoline(self) + class FlexSwitchCaseGenerator(MethodGenerator): flexswitch = None value = -1 linkargs_gv = None linkargs_gv_map = None + method_id = 10 # XXX + def set_parent_flexswitch(self, flexswitch, value): self.parent_flexswitch = flexswitch self.value = value @@ -651,6 +692,7 @@ linkargs_out_gv.append(gv_var) args_manager.copy_from_inputargs(self, linkargs_out_gv) + class BranchBuilder(GenBuilder): def __init__(self, meth, il_label): @@ -783,14 +825,14 @@ return self._jump_if(gv_condition, OpCodes.Brtrue) def flexswitch(self, gv_exitswitch, args_gv): - # XXX: this code is valid only for GraphGenerator + # XXX: this code is valid only for MainMethod self.meth.setup_flexswitches() flexswitch = IntFlexSwitch(self.meth, args_gv) gv_flexswitch = flexswitch.gv_flexswitch default_branch = self.meth.newbranch() label = default_branch.enter_next_block(args_gv) - flexswitch.llflexswitch.set_default_blockid(label.blockid) + flexswitch.llflexswitch.set_default_blockid(label.block_id) op = ops.DoFlexSwitch(self.meth, gv_flexswitch, gv_exitswitch, args_gv) self.appendop(op) @@ -828,7 +870,6 @@ graphinfo = graph.graphinfo meth = FlexSwitchCaseGenerator(graph.rgenop, name, restype, arglist, delegatetype, graphinfo) - graphinfo.flexswitch_meths.append(meth) value = gv_case.revealconst(ootype.Signed) meth.set_parent_flexswitch(self, value) meth.set_linkargs_gv(self.linkargs_gv) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py Tue Oct 21 16:28:25 2008 @@ -84,6 +84,9 @@ def test_interior_access(self): py.test.skip('fixme') + def test_switch_goto_between_flexswitches_direct(self): + py.test.skip('fixme') + class TestRCliGenopCompile(AbstractRGenOpTestsCompile): RGenOp = RCliGenOp @@ -142,3 +145,6 @@ def test_ovfcheck1_compile(self): py.test.skip('fixme') + + def test_switch_goto_between_flexswitches_compile(self): + py.test.skip('fixme') From antocuni at codespeak.net Tue Oct 21 17:24:22 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 21 Oct 2008 17:24:22 +0200 (CEST) Subject: [pypy-svn] r59302 - in pypy/branch/oo-jit/pypy: jit/codegen/cli translator/cli/src Message-ID: <20081021152422.BA98016A10A@codespeak.net> Author: antocuni Date: Tue Oct 21 17:24:20 2008 New Revision: 59302 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Log: (IN-PROGRESS) more refactoring; now all the FlexCaseMethods have their own dispatch block. Still need to do the proper transformation from block_id to block_num, and to handle non-local jumps Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py Tue Oct 21 17:24:20 2008 @@ -308,18 +308,13 @@ args_manager.copy_to_inputargs(graph, self.args_gv) # jumpto = flexswitch.execute(exitswitch, inputargs); - # goto dispatch_jump; + # goto dispatch_block; self.gv_flexswitch.load(graph) self.gv_exitswitch.load(graph) graph.gv_inputargs.load(graph) il.Emit(OpCodes.Callvirt, meth_execute) - if graph.jumpto_var is None: - # we are inside a nested flexswitch, just return to parent - il.Emit(OpCodes.Ret) - else: - # we are in the main method, do the dispatching - il.Emit(OpCodes.Stloc, graph.jumpto_var) - il.Emit(OpCodes.Br, graph.il_dispatch_jump_label) + il.Emit(OpCodes.Stloc, graph.jumpto_var) + il.Emit(OpCodes.Br, graph.il_dispatch_block_label) class WriteLine(Operation): Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Tue Oct 21 17:24:20 2008 @@ -450,11 +450,11 @@ - MainMethod: the method containing the first block of the graph, and all the blocks reachable without passing throgh a flexswitch - - CaseMethod: a method containing the blocks for a specific case of a + - FlexCaseMethod: a method containing the blocks for a specific case of a flexswitch - method_id: unique 16 bit number that identifies a method (either MainMethod or - CaseMethod) inside a graph. MainMethod.method_id == 0 + FlexCaseMethod) inside a graph. MainMethod.method_id == 0 - block_num: unique 16 bit number that identifies a block inside a method @@ -552,7 +552,7 @@ for branchbuilder in self.branches: branchbuilder.replayops() - # emit dispatch_jump, if there are flexswitches + # emit dispatch_block, if there are flexswitches self.emit_before_returnblock() # emit the return block at last, else the verifier complains @@ -577,9 +577,35 @@ pass def setup_dispatch_block(self): - self.il_dispatch_jump_label = self.il.DefineLabel() + self.il_dispatch_block_label = self.il.DefineLabel() self.jumpto_var = self.il.DeclareLocal(class2type(cInt32)) + def emit_dispatch_block(self): + # make sure we don't enter dispatch_block by mistake + self.il.Emit(OpCodes.Br, self.retlabel.il_label) + self.il.MarkLabel(self.il_dispatch_block_label) + + blocks = self.blocks + il_labels = new_array(System.Reflection.Emit.Label, len(blocks)) + for block_num in range(len(blocks)): + label = blocks[block_num] + il_labels[block_num] = label.il_trampoline_label + + # XXX: do the right thing if no block was found + # (depends if we are in the MainMethod or in a FlexCaseMethod) + + self.il.Emit(OpCodes.Ldloc, self.jumpto_var) + self.il.Emit(OpCodes.Switch, il_labels) + # default: Utils.throwInvalidBlockId(jumpto) + clitype = class2type(cUtils) + meth = clitype.GetMethod("throwInvalidBlockId") + self.il.Emit(OpCodes.Ldloc, self.jumpto_var) + self.il.Emit(OpCodes.Call, meth) + + # emit all the trampolines to the blocks + for label in blocks: + label.emit_trampoline(self) + class MainMethod(MethodGenerator): @@ -603,11 +629,9 @@ def emit_preamble(self): if not self.has_flexswitches: return - # compute the shape of InputArgs args_manager = self.graphinfo.args_manager args_manager.close() - # InputArgs inputargs = new InputArgs() self.gv_inputargs = self.newlocalvar(args_manager.getCliType()) clitype = self.gv_inputargs.getCliType() @@ -618,33 +642,11 @@ def emit_before_returnblock(self): if not self.has_flexswitches: return - # make sure we don't enter dispatch_jump by mistake - self.il.Emit(OpCodes.Br, self.retlabel.il_label) - self.il.MarkLabel(self.il_dispatch_jump_label) + self.emit_dispatch_block() - blocks = self.blocks - il_labels = new_array(System.Reflection.Emit.Label, len(blocks)) - for block_num in range(len(blocks)): - label = blocks[block_num] - il_labels[block_num] = label.il_trampoline_label - # XXX: call the right case if no block was found - - #print 'Emitting dispatch switch' - self.il.Emit(OpCodes.Ldloc, self.jumpto_var) - self.il.Emit(OpCodes.Switch, il_labels) - # XXX: handle block_ids that are inside flexswitch cases - # default: Utils.throwInvalidBlockId(jumpto) - clitype = class2type(cUtils) - meth = clitype.GetMethod("throwInvalidBlockId") - self.il.Emit(OpCodes.Ldloc, self.jumpto_var) - self.il.Emit(OpCodes.Call, meth) - - # emit all the trampolines to the blocks - for label in blocks: - label.emit_trampoline(self) -class FlexSwitchCaseGenerator(MethodGenerator): +class FlexCaseMethod(MethodGenerator): flexswitch = None value = -1 linkargs_gv = None @@ -655,6 +657,7 @@ def set_parent_flexswitch(self, flexswitch, value): self.parent_flexswitch = flexswitch self.value = value + self.setup_dispatch_block() def set_linkargs_gv(self, linkargs_gv): self.linkargs_gv = linkargs_gv @@ -678,7 +681,10 @@ self.parent_flexswitch.llflexswitch.add_case(self.value, func2) def emit_preamble(self): - # InputArgs inputargs = (InputArgs)obj // obj is the 2nd arg + # the signature of the method is + # int case_0(int jumpto, object args) + + # InputArgs inputargs = (InputArgs)obj args_manager = self.graphinfo.args_manager clitype = args_manager.getCliType() self.gv_inputargs = self.newlocalvar(clitype) @@ -686,6 +692,16 @@ self.il.Emit(OpCodes.Castclass, clitype) self.gv_inputargs.store(self) + # 0 is a special value that means "first block of the function", + # i.e. don't go through the dispatch block. 0 can never passed as + # blockid, because it's used as the returnblock of the MainMethod, and + # it's handled by its dispatch block + + # if (jumpto != 0) goto dispatch_block + self.inputargs_gv[0].load(self) + self.il.Emit(OpCodes.Ldc_I4_0) + self.il.Emit(OpCodes.Bne_Un, self.il_dispatch_block_label) + linkargs_out_gv = [] for gv_linkarg in self.linkargs_gv: gv_var = self.linkargs_gv_map[gv_linkarg] @@ -693,6 +709,11 @@ args_manager.copy_from_inputargs(self, linkargs_out_gv) + def emit_before_returnblock(self): + self.emit_dispatch_block() + + + class BranchBuilder(GenBuilder): def __init__(self, meth, il_label): @@ -868,8 +889,8 @@ arglist = [class2type(cInt32), class2type(cObject)] delegatetype = class2type(cFlexSwitchCase) graphinfo = graph.graphinfo - meth = FlexSwitchCaseGenerator(graph.rgenop, name, restype, - arglist, delegatetype, graphinfo) + meth = FlexCaseMethod(graph.rgenop, name, restype, + arglist, delegatetype, graphinfo) value = gv_case.revealconst(ootype.Signed) meth.set_parent_flexswitch(self, value) meth.set_linkargs_gv(self.linkargs_gv) Modified: pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Tue Oct 21 17:24:20 2008 @@ -156,7 +156,9 @@ { for(int i=0; i Author: antocuni Date: Wed Oct 22 13:31:22 2008 New Revision: 59309 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Log: use unsigned int instead of int to store the blockid Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py Wed Oct 22 13:31:22 2008 @@ -1,5 +1,6 @@ import py from pypy.rlib.objectmodel import specialize +from pypy.rlib.rarithmetic import intmask from pypy.rpython.ootypesystem import ootype from pypy.translator.cli.dotnet import CLR, typeof, new_array from pypy.translator.cli import opcodes as cli_opcodes @@ -149,7 +150,7 @@ graphinfo.args_manager.copy_to_inputargs(self.meth, self.args_gv) block_id = self.target.block_id #import pdb;pdb.set_trace() - il.Emit(OpCodes.Ldc_I4, block_id) + il.Emit(OpCodes.Ldc_I4, intmask(block_id)) il.Emit(OpCodes.Ret) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Wed Oct 22 13:31:22 2008 @@ -3,6 +3,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem import lltype from pypy.rlib.objectmodel import specialize +from pypy.rlib.rarithmetic import r_uint from pypy.jit.codegen.model import AbstractRGenOp, GenBuilder, GenLabel from pypy.jit.codegen.model import GenVarOrConst, GenVar, GenConst from pypy.jit.codegen.model import CodeGenSwitch @@ -464,8 +465,12 @@ class GraphInfo: def __init__(self): - #self.blocks = [] # block_id -> (meth, label) self.args_manager = ArgsManager() + + # allocate space for the return variable of FlexCaseMethod + # XXX: it should be handled automatically :-( + self.args_manager.register_types([typeof(System.UInt32)]) + class MethodGenerator: @@ -511,15 +516,10 @@ return branch def newblock(self, args_gv): -## blocks = self.graphinfo.blocks -## block_id = len(blocks) -## result = Label(self, block_id, args_gv) -## blocks.append((self, result)) - block_num = len(self.blocks) assert block_num < 2**16 assert self.method_id >= 0 - block_id = self.method_id << 16 | block_num + block_id = r_uint(self.method_id) << 16 | block_num lbl = Label(self, block_id, args_gv) self.blocks.append(lbl) self.graphinfo.args_manager.register(args_gv) @@ -578,7 +578,7 @@ def setup_dispatch_block(self): self.il_dispatch_block_label = self.il.DefineLabel() - self.jumpto_var = self.il.DeclareLocal(class2type(cInt32)) + self.jumpto_var = self.il.DeclareLocal(typeof(System.UInt32)) def emit_dispatch_block(self): # make sure we don't enter dispatch_block by mistake @@ -885,8 +885,8 @@ def add_case(self, gv_case): graph = self.graph name = graph.name + '_case' - restype = class2type(cInt32) - arglist = [class2type(cInt32), class2type(cObject)] + restype = typeof(System.UInt32) + arglist = [typeof(System.UInt32), class2type(cObject)] delegatetype = class2type(cFlexSwitchCase) graphinfo = graph.graphinfo meth = FlexCaseMethod(graph.rgenop, name, restype, Modified: pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Wed Oct 22 13:31:22 2008 @@ -117,16 +117,16 @@ public T fields; } - public delegate int FlexSwitchCase(int block, object args); + public delegate uint FlexSwitchCase(uint block, object args); public class LowLevelFlexSwitch { - public int default_blockid = -1; + public uint default_blockid = 0xFFFFFFFF; public int numcases = 0; public int[] values = new int[4]; public FlexSwitchCase[] cases = new FlexSwitchCase[4]; - public void set_default_blockid(int blockid) + public void set_default_blockid(uint blockid) { this.default_blockid = blockid; } @@ -152,7 +152,7 @@ cases = newcases; } - public int execute(int v, object args) + public uint execute(int v, object args) { for(int i=0; i Author: arigo Date: Wed Oct 22 14:20:25 2008 New Revision: 59313 Added: pypy/branch/dist-trunk-merge/ - copied from r59312, pypy/trunk/ Log: This looks like it's again going to be a mess, so here is a branch (a copy of 'trunk') in which to try to merge 'dist'. From antocuni at codespeak.net Wed Oct 22 16:26:48 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 22 Oct 2008 16:26:48 +0200 (CEST) Subject: [pypy-svn] r59316 - in pypy/branch/oo-jit/pypy/jit/codegen/cli: . test Message-ID: <20081022142648.1F69C16A1FE@codespeak.net> Author: antocuni Date: Wed Oct 22 16:26:47 2008 New Revision: 59316 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py Log: when you are in a FlexCaseMethod and want to jump to an unknown block, just delegate the jump to the parent, and let the MainMethod to do it. This simple test pass, but more complex cases are expected to fail Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Wed Oct 22 16:26:47 2008 @@ -582,8 +582,9 @@ def emit_dispatch_block(self): # make sure we don't enter dispatch_block by mistake - self.il.Emit(OpCodes.Br, self.retlabel.il_label) - self.il.MarkLabel(self.il_dispatch_block_label) + il = self.il + il.Emit(OpCodes.Br, self.retlabel.il_label) + il.MarkLabel(self.il_dispatch_block_label) blocks = self.blocks il_labels = new_array(System.Reflection.Emit.Label, len(blocks)) @@ -594,18 +595,34 @@ # XXX: do the right thing if no block was found # (depends if we are in the MainMethod or in a FlexCaseMethod) - self.il.Emit(OpCodes.Ldloc, self.jumpto_var) - self.il.Emit(OpCodes.Switch, il_labels) + # if (((jumpto & 0xFFFF0000) >> 16) != method_id) + # goto jump_to_unknown + il_jump_to_unknown_label = il.DefineLabel() + il.Emit(OpCodes.Ldloc, self.jumpto_var) + il.Emit(OpCodes.Ldc_I4, intmask(0xFFF0000)) + il.Emit(OpCodes.And) + il.Emit(OpCodes.Ldc_I4, 16) + il.Emit(OpCodes.Shr_Un) + il.Emit(OpCodes.Ldc_I4, self.method_id) + il.Emit(OpCodes.Bne_Un, il_jump_to_unknown_label) + + # switch(jumpto && 0x0000FFFF) + il.Emit(OpCodes.Ldloc, self.jumpto_var) + il.Emit(OpCodes.Ldc_I4, 0x0000FFFF) + il.Emit(OpCodes.And) + il.Emit(OpCodes.Switch, il_labels) # default: Utils.throwInvalidBlockId(jumpto) clitype = class2type(cUtils) meth = clitype.GetMethod("throwInvalidBlockId") - self.il.Emit(OpCodes.Ldloc, self.jumpto_var) - self.il.Emit(OpCodes.Call, meth) + il.Emit(OpCodes.Ldloc, self.jumpto_var) + il.Emit(OpCodes.Call, meth) # emit all the trampolines to the blocks for label in blocks: label.emit_trampoline(self) + self.emit_jump_to_unknown_block(il_jump_to_unknown_label) + class MainMethod(MethodGenerator): @@ -644,6 +661,15 @@ return self.emit_dispatch_block() + def emit_jump_to_unknown_block(self, il_label): + # just throw an exception for now + il = self.il + il.MarkLabel(il_label) + clitype = class2type(cUtils) + meth = clitype.GetMethod("throwInvalidBlockId") + #il.Emit(OpCodes.Ldloc, self.jumpto_var) + il.Emit(OpCodes.Ldc_I4, 4242) + il.Emit(OpCodes.Call, meth) class FlexCaseMethod(MethodGenerator): @@ -654,6 +680,9 @@ method_id = 10 # XXX + def setup_flexswitches(self): + pass + def set_parent_flexswitch(self, flexswitch, value): self.parent_flexswitch = flexswitch self.value = value @@ -712,7 +741,12 @@ def emit_before_returnblock(self): self.emit_dispatch_block() - + def emit_jump_to_unknown_block(self, il_label): + # delegate to parent + il = self.il + il.MarkLabel(il_label) + il.Emit(OpCodes.Ldloc, self.jumpto_var) + il.Emit(OpCodes.Ret) class BranchBuilder(GenBuilder): Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py Wed Oct 22 16:26:47 2008 @@ -84,9 +84,6 @@ def test_interior_access(self): py.test.skip('fixme') - def test_switch_goto_between_flexswitches_direct(self): - py.test.skip('fixme') - class TestRCliGenopCompile(AbstractRGenOpTestsCompile): RGenOp = RCliGenOp @@ -145,6 +142,3 @@ def test_ovfcheck1_compile(self): py.test.skip('fixme') - - def test_switch_goto_between_flexswitches_compile(self): - py.test.skip('fixme') From antocuni at codespeak.net Wed Oct 22 16:47:44 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 22 Oct 2008 16:47:44 +0200 (CEST) Subject: [pypy-svn] r59317 - pypy/branch/oo-jit/pypy/jit/codegen/cli/test Message-ID: <20081022144744.80EF316A1AB@codespeak.net> Author: antocuni Date: Wed Oct 22 16:47:43 2008 New Revision: 59317 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py Log: good, this test passes now Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py Wed Oct 22 16:47:43 2008 @@ -10,7 +10,6 @@ def skip(self): py.test.skip('in progress') - test_two_promotions = skip more_promotes = skip mixed_merges = skip remembers_across_mp = skip From arigo at codespeak.net Wed Oct 22 16:52:13 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 22 Oct 2008 16:52:13 +0200 (CEST) Subject: [pypy-svn] r59319 - pypy/branch/oo-jit/pypy/rpython Message-ID: <20081022145213.3E9A916A225@codespeak.net> Author: arigo Date: Wed Oct 22 16:52:12 2008 New Revision: 59319 Modified: pypy/branch/oo-jit/pypy/rpython/rlist.py Log: A further hack in this function, to allow it to be directly executed. Modified: pypy/branch/oo-jit/pypy/rpython/rlist.py ============================================================================== --- pypy/branch/oo-jit/pypy/rpython/rlist.py (original) +++ pypy/branch/oo-jit/pypy/rpython/rlist.py Wed Oct 22 16:52:12 2008 @@ -8,7 +8,7 @@ from pypy.rpython.lltypesystem.lltype import typeOf, Ptr, Void, Signed, Bool from pypy.rpython.lltypesystem.lltype import nullptr, Char, UniChar from pypy.rpython import robject -from pypy.rlib.objectmodel import malloc_zero_filled +from pypy.rlib.objectmodel import malloc_zero_filled, we_are_translated from pypy.rlib.debug import ll_assert from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.annlowlevel import ADTInterface @@ -495,7 +495,8 @@ check = ord(item) else: check = item - if (not malloc_zero_filled) or check: # as long as malloc it is known to zero the allocated memory avoid zeroing twice + zero_filled = we_are_translated() and malloc_zero_filled + if (not zero_filled) or check: # as long as malloc it is known to zero the allocated memory avoid zeroing twice i = 0 while i < count: From arigo at codespeak.net Wed Oct 22 18:37:48 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 22 Oct 2008 18:37:48 +0200 (CEST) Subject: [pypy-svn] r59324 - pypy/branch/dist-trunk-merge Message-ID: <20081022163748.3E11716A14D@codespeak.net> Author: arigo Date: Wed Oct 22 18:37:47 2008 New Revision: 59324 Removed: pypy/branch/dist-trunk-merge/ Log: Remove merged branch. From iko at codespeak.net Thu Oct 23 01:32:47 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Thu, 23 Oct 2008 01:32:47 +0200 (CEST) Subject: [pypy-svn] r59327 - pypy/trunk/pypy/objspace/std Message-ID: <20081022233247.64109169FF1@codespeak.net> Author: iko Date: Thu Oct 23 01:32:45 2008 New Revision: 59327 Modified: pypy/trunk/pypy/objspace/std/tupleobject.py Log: Dont short-circuit subtype_of_tuple * 1 Modified: pypy/trunk/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/tupleobject.py (original) +++ pypy/trunk/pypy/objspace/std/tupleobject.py Thu Oct 23 01:32:45 2008 @@ -80,7 +80,7 @@ if e.match(space, space.w_TypeError): raise FailedToImplement raise - if times == 1: + if times == 1 and space.type(w_tuple) == space.w_tuple: return w_tuple items = w_tuple.wrappeditems return W_TupleObject(items * times) From iko at codespeak.net Thu Oct 23 01:34:47 2008 From: iko at codespeak.net (iko at codespeak.net) Date: Thu, 23 Oct 2008 01:34:47 +0200 (CEST) Subject: [pypy-svn] r59328 - pypy/trunk/pypy/objspace/std/test Message-ID: <20081022233447.0D28416A023@codespeak.net> Author: iko Date: Thu Oct 23 01:34:46 2008 New Revision: 59328 Modified: pypy/trunk/pypy/objspace/std/test/test_tupleobject.py Log: test for previous checkin Modified: pypy/trunk/pypy/objspace/std/test/test_tupleobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_tupleobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_tupleobject.py Thu Oct 23 01:34:46 2008 @@ -283,6 +283,12 @@ t = (1,2,3) assert (t * 1) is t + def test_mul_subtype(self): + class T(tuple): pass + t = T([1,2,3]) + assert (t * 1) is not t + assert (t * 1) == t + def test_getslice(self): assert (5,2,3)[1:2] == (2,) From fijal at codespeak.net Thu Oct 23 12:32:08 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 23 Oct 2008 12:32:08 +0200 (CEST) Subject: [pypy-svn] r59329 - in pypy/trunk/pypy: . annotation config config/test module/_minimal_curses module/_rawffi/test rlib rlib/rsdl rlib/test rpython/module rpython/tool tool tool/test translator translator/c translator/c/src translator/c/test translator/goal translator/platform translator/platform/test translator/platform/test/include translator/sandbox/test translator/test translator/tool translator/tool/test Message-ID: <20081023103208.823B216A0EE@codespeak.net> Author: fijal Date: Thu Oct 23 12:32:04 2008 New Revision: 59329 Added: pypy/trunk/pypy/translator/c/src/allocator.h - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/c/src/allocator.h pypy/trunk/pypy/translator/platform/ (props changed) - copied from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/ pypy/trunk/pypy/translator/platform/__init__.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/__init__.py pypy/trunk/pypy/translator/platform/darwin.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/darwin.py pypy/trunk/pypy/translator/platform/distutils_platform.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/distutils_platform.py pypy/trunk/pypy/translator/platform/linux.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/linux.py pypy/trunk/pypy/translator/platform/maemo.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/maemo.py pypy/trunk/pypy/translator/platform/posix.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/posix.py pypy/trunk/pypy/translator/platform/test/ (props changed) - copied from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/test/ pypy/trunk/pypy/translator/platform/test/__init__.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/test/__init__.py pypy/trunk/pypy/translator/platform/test/include/ - copied from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/test/include/ pypy/trunk/pypy/translator/platform/test/include/test.h - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/test/include/test.h pypy/trunk/pypy/translator/platform/test/test_distutils.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_distutils.py pypy/trunk/pypy/translator/platform/test/test_maemo.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_maemo.py pypy/trunk/pypy/translator/platform/test/test_makefile.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_makefile.py pypy/trunk/pypy/translator/platform/test/test_platform.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_platform.py pypy/trunk/pypy/translator/platform/test/test_posix.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/test/test_posix.py pypy/trunk/pypy/translator/platform/windows.py - copied unchanged from r59328, pypy/branch/cbuild-refactor/pypy/translator/platform/windows.py Removed: pypy/trunk/pypy/rlib/pyplatform.py Modified: pypy/trunk/pypy/annotation/model.py pypy/trunk/pypy/config/pypyoption.py pypy/trunk/pypy/config/test/test_pypyoption.py pypy/trunk/pypy/config/translationoption.py pypy/trunk/pypy/conftest.py pypy/trunk/pypy/module/_minimal_curses/interp_curses.py pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py pypy/trunk/pypy/rlib/libffi.py pypy/trunk/pypy/rlib/rsdl/eci.py pypy/trunk/pypy/rlib/test/test_libffi.py pypy/trunk/pypy/rpython/module/ll_strtod.py pypy/trunk/pypy/rpython/tool/rffi_platform.py pypy/trunk/pypy/tool/gcc_cache.py pypy/trunk/pypy/tool/test/test_gcc_cache.py pypy/trunk/pypy/translator/c/genc.py pypy/trunk/pypy/translator/c/src/g_include.h pypy/trunk/pypy/translator/c/src/signals.h pypy/trunk/pypy/translator/c/src/standalone.h pypy/trunk/pypy/translator/c/src/thread_nt.h pypy/trunk/pypy/translator/c/test/test_boehm.py pypy/trunk/pypy/translator/c/test/test_extfunc.py pypy/trunk/pypy/translator/c/test/test_genc.py pypy/trunk/pypy/translator/c/test/test_rtagged.py pypy/trunk/pypy/translator/c/test/test_stackless.py pypy/trunk/pypy/translator/c/test/test_standalone.py pypy/trunk/pypy/translator/c/test/test_typed.py pypy/trunk/pypy/translator/driver.py pypy/trunk/pypy/translator/goal/translate.py pypy/trunk/pypy/translator/sandbox/test/test_pypy_interact.py pypy/trunk/pypy/translator/sandbox/test/test_sandbox.py pypy/trunk/pypy/translator/sandbox/test/test_sandlib.py pypy/trunk/pypy/translator/test/test_geninterp.py pypy/trunk/pypy/translator/tool/cbuild.py pypy/trunk/pypy/translator/tool/test/test_cbuild.py pypy/trunk/pypy/translator/translator.py Log: Merge cbuild-refactor branch using: svn merge -r 58880:HEAD http://codespeak.net/svn/pypy/branch/cbuild-refactor/pypy . This branch contains: * Factored out translator/platform which should encode all platform details * Removal of rlib/pyplatform.py * Move away from distutils both for linux and windows. * Provide distutils fallback platform Modified: pypy/trunk/pypy/annotation/model.py ============================================================================== --- pypy/trunk/pypy/annotation/model.py (original) +++ pypy/trunk/pypy/annotation/model.py Thu Oct 23 12:32:04 2008 @@ -37,7 +37,7 @@ from pypy.rlib.rarithmetic import r_singlefloat import inspect, weakref -DEBUG = True # set to False to disable recording of debugging information +DEBUG = False # set to False to disable recording of debugging information TLS = tlsobject() class SomeObject: Modified: pypy/trunk/pypy/config/pypyoption.py ============================================================================== --- pypy/trunk/pypy/config/pypyoption.py (original) +++ pypy/trunk/pypy/config/pypyoption.py Thu Oct 23 12:32:04 2008 @@ -36,12 +36,16 @@ ["md5", "sha", "cStringIO", "itertools"] )) +# XXX this should move somewhere else, maybe to platform ("is this posixish" +# check or something) if sys.platform == "win32": # unix only modules del working_modules["crypt"] del working_modules["fcntl"] del working_modules["termios"] del working_modules["_minimal_curses"] + # XXX this is temporary, hopefully + del working_modules["bz2"] if sys.platform == "sunos5": del working_modules['mmap'] # depend on ctypes, can'T get at c-level 'errono' Modified: pypy/trunk/pypy/config/test/test_pypyoption.py ============================================================================== --- pypy/trunk/pypy/config/test/test_pypyoption.py (original) +++ pypy/trunk/pypy/config/test/test_pypyoption.py Thu Oct 23 12:32:04 2008 @@ -41,7 +41,7 @@ assert not conf.translation.backendopt.none conf = get_pypy_config() set_opt_level(conf, 'mem') - assert conf.translation.gc == 'marksweep' + assert conf.translation.gc == 'markcompact' assert not conf.translation.backendopt.none def test_set_pypy_opt_level(): Modified: pypy/trunk/pypy/config/translationoption.py ============================================================================== --- pypy/trunk/pypy/config/translationoption.py (original) +++ pypy/trunk/pypy/config/translationoption.py Thu Oct 23 12:32:04 2008 @@ -11,6 +11,12 @@ DEFL_CLEVER_MALLOC_REMOVAL_INLINE_THRESHOLD = 32.4 DEFL_LOW_INLINE_THRESHOLD = DEFL_INLINE_THRESHOLD / 2.0 +PLATFORMS = [ + 'maemo', + 'host', + 'distutils', +] + translation_optiondescription = OptionDescription( "translation", "Translation Options", [ BoolOption("stackless", "enable stackless features during compilation", @@ -255,6 +261,10 @@ cmdline="--cli-trace-calls"), BoolOption("exception_transformer", "Use exception transformer", default=False), ]), + ChoiceOption("platform", + "target platform", ['host'] + PLATFORMS, default='host', + cmdline='--platform'), + ]) def get_combined_translation_config(other_optdescr=None, @@ -351,21 +361,12 @@ # ---------------------------------------------------------------- -PLATFORMS = [ - 'host', - 'maemo', -] - -def set_platform(config, platform): - from pypy.rlib.pyplatform import Platform, Maemo - from pypy.rlib import pyplatform - from pypy.translator.tool.cbuild import ExternalCompilationInfo - if isinstance(platform, str): - if platform == 'maemo': - platform = Maemo(cc=config.translation.cc or None) - elif platform == 'host': - return - else: - raise NotImplementedError('Platform = %s' % (platform,)) - assert isinstance(platform, Platform) - pyplatform.platform = platform +def set_platform(config): + from pypy.translator.platform import set_platform + set_platform(config.translation.platform, config.translation.cc) + +def get_platform(config): + from pypy.translator.platform import pick_platform + opt = config.translation.platform + cc = config.translation.cc + return pick_platform(opt, cc) Modified: pypy/trunk/pypy/conftest.py ============================================================================== --- pypy/trunk/pypy/conftest.py (original) +++ pypy/trunk/pypy/conftest.py Thu Oct 23 12:32:04 2008 @@ -20,6 +20,13 @@ # Option = py.test.config.Option +def _set_platform(opt, opt_str, value, parser): + from pypy.config.translationoption import PLATFORMS + from pypy.translator.platform import set_platform + value = parser.rargs.pop(0) + if value not in PLATFORMS: + raise ValueError("%s not in %s" % (value, PLATFORMS)) + set_platform(value, None) option = py.test.config.addoptions("pypy options", Option('--view', action="store_true", dest="view", default=False, @@ -30,6 +37,9 @@ Option('--direct', action="store_true", default=False, dest="rundirect", help="run pexpect tests directly"), + Option('-P', '--platform', action="callback", + default="host", callback=_set_platform, + help="set up tests to use specified platform as compile/run target"), ) @@ -167,7 +177,7 @@ """ we take care of collecting classes both at app level and at interp-level (because we need to stick a space at the class) ourselves. - """ + """ def __init__(self, *args, **kwargs): if hasattr(sys, 'pypy_objspaceclass'): option.conf_iocapture = "sys" # pypy cannot do FD-based Modified: pypy/trunk/pypy/module/_minimal_curses/interp_curses.py ============================================================================== --- pypy/trunk/pypy/module/_minimal_curses/interp_curses.py (original) +++ pypy/trunk/pypy/module/_minimal_curses/interp_curses.py Thu Oct 23 12:32:04 2008 @@ -21,7 +21,7 @@ def convert_error(space, error): msg = error.msg - w_module = space.getbuiltinmodule('_curses') + w_module = space.getbuiltinmodule('_minimal_curses') w_exception_class = space.getattr(w_module, space.wrap('error')) w_exception = space.call_function(w_exception_class, space.wrap(msg)) return OperationError(w_exception_class, w_exception) Modified: pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py ============================================================================== --- pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py (original) +++ pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py Thu Oct 23 12:32:04 2008 @@ -5,6 +5,7 @@ ExternalCompilationInfo from pypy.module._rawffi.interp_rawffi import TYPEMAP from pypy.module._rawffi.tracker import Tracker +from pypy.translator.platform import platform import os, sys, py @@ -154,7 +155,7 @@ give perturb """.split() eci = ExternalCompilationInfo(export_symbols=symbols) - return compile_c_module([c_file], 'x', eci) + return str(platform.compile([c_file], eci, 'x', standalone=False)) prepare_c_example = staticmethod(prepare_c_example) def setup_class(cls): Modified: pypy/trunk/pypy/rlib/libffi.py ============================================================================== --- pypy/trunk/pypy/rlib/libffi.py (original) +++ pypy/trunk/pypy/rlib/libffi.py Thu Oct 23 12:32:04 2008 @@ -16,26 +16,21 @@ import ctypes.util DEBUG = False # writes dlerror() messages to stderr +# XXX this need solving rather than hacking. We need to raise something else +# than OSError, something capable of delivering a message -_MS_WINDOWS = os.name == "nt" -_MAC_OS = sys.platform == "darwin" +from pypy.translator.platform import platform + +# maaaybe isinstance here would be better. Think +_MS_WINDOWS = platform.name == "win32" +_MAC_OS = platform.name == "darwin" if _MS_WINDOWS: from pypy.rlib import rwin32 if not _MS_WINDOWS: includes = ['dlfcn.h', 'ffi.h'] - include_dirs = [] - if _MAC_OS: - pot_incl = py.path.local('/usr/include/ffi') - else: - pot_incl = py.path.local('/usr/include/libffi') - if pot_incl.check(): - include_dirs.append(str(pot_incl)) - lib_dirs = [] - pot_lib = py.path.local('/usr/lib/libffi') - if pot_lib.check(): - lib_dirs.append(str(pot_lib)) + include_dirs = platform.include_dirs_for_libffi() if _MAC_OS: pre_include_bits = ['#define MACOSX'] @@ -45,8 +40,8 @@ pre_include_bits = pre_include_bits, includes = includes, libraries = ['ffi', 'dl'], - include_dirs = include_dirs, - library_dirs = lib_dirs, + include_dirs = platform.include_dirs_for_libffi(), + library_dirs = platform.library_dirs_for_libffi(), ) else: libffidir = py.path.local(pypydir).join('translator', 'c', 'src', 'libffi_msvc') Modified: pypy/trunk/pypy/rlib/rsdl/eci.py ============================================================================== --- pypy/trunk/pypy/rlib/rsdl/eci.py (original) +++ pypy/trunk/pypy/rlib/rsdl/eci.py Thu Oct 23 12:32:04 2008 @@ -1,5 +1,5 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.translator.tool.cbuild import CompilationError +from pypy.translator.platform import CompilationError import py import sys Modified: pypy/trunk/pypy/rlib/test/test_libffi.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_libffi.py (original) +++ pypy/trunk/pypy/rlib/test/test_libffi.py Thu Oct 23 12:32:04 2008 @@ -229,8 +229,8 @@ lltype.free(tp, flavor='raw') def test_struct_by_val(self): - from pypy.translator.tool.cbuild import compile_c_module, \ - ExternalCompilationInfo + from pypy.translator.tool.cbuild import ExternalCompilationInfo + from pypy.translator.platform import platform from pypy.tool.udir import udir c_file = udir.ensure("test_libffi", dir=1).join("xlib.c") @@ -253,7 +253,7 @@ ''')) eci = ExternalCompilationInfo(export_symbols=['sum_x_y']) - lib_name = compile_c_module([c_file], 'x', eci) + lib_name = str(platform.compile([c_file], eci, 'x', standalone=False)) lib = CDLL(lib_name) @@ -280,8 +280,8 @@ assert not ALLOCATED def test_ret_struct_val(self): - from pypy.translator.tool.cbuild import compile_c_module, \ - ExternalCompilationInfo + from pypy.translator.tool.cbuild import ExternalCompilationInfo + from pypy.translator.platform import platform from pypy.tool.udir import udir c_file = udir.ensure("test_libffi", dir=1).join("xlib.c") @@ -309,7 +309,7 @@ ''')) eci = ExternalCompilationInfo(export_symbols=['give', 'perturb']) - lib_name = compile_c_module([c_file], 'x', eci) + lib_name = str(platform.compile([c_file], eci, 'x', standalone=False)) lib = CDLL(lib_name) Modified: pypy/trunk/pypy/rpython/module/ll_strtod.py ============================================================================== --- pypy/trunk/pypy/rpython/module/ll_strtod.py (original) +++ pypy/trunk/pypy/rpython/module/ll_strtod.py Thu Oct 23 12:32:04 2008 @@ -7,10 +7,12 @@ from pypy.rpython.ootypesystem import ootype from pypy.rlib import rposix from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.tool.autopath import pypydir class CConfig: _compilation_info_ = ExternalCompilationInfo( includes = ['src/ll_strtod.h'], + include_dirs = [str(py.path.local(pypydir).join('translator', 'c'))], separate_module_sources = ['#include '], export_symbols = ['LL_strtod_formatd', 'LL_strtod_parts_to_float'], ) Modified: pypy/trunk/pypy/rpython/tool/rffi_platform.py ============================================================================== --- pypy/trunk/pypy/rpython/tool/rffi_platform.py (original) +++ pypy/trunk/pypy/rpython/tool/rffi_platform.py Thu Oct 23 12:32:04 2008 @@ -6,7 +6,7 @@ from pypy.rpython.lltypesystem import llmemory from pypy.tool.gcc_cache import build_executable_cache, try_compile_cache from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.translator.tool.cbuild import CompilationError +from pypy.translator.platform import CompilationError from pypy.tool.udir import udir import distutils @@ -538,7 +538,7 @@ def run_example_code(filepath, eci): eci = eci.convert_sources_to_files(being_main=True) - files = [filepath] + [py.path.local(f) for f in eci.separate_module_files] + files = [filepath] output = build_executable_cache(files, eci) section = None for line in output.splitlines(): @@ -561,6 +561,21 @@ gcv = sysconfig.get_config_vars() return gcv['INCLUDEPY'] +def check_boehm(platform=None, cache={}): + if platform is None: + from pypy.translator.platform import platform + try: + return cache[platform] + except KeyError: + class CConfig: + _compilation_info_ = ExternalCompilationInfo( + includes=['gc/gc.h'], + platform=platform, + ) + HAS = Has('GC_init') + cache[platform] = configure(CConfig)['HAS'] + return cache[platform] + if __name__ == '__main__': doc = """Example: Modified: pypy/trunk/pypy/tool/gcc_cache.py ============================================================================== --- pypy/trunk/pypy/tool/gcc_cache.py (original) +++ pypy/trunk/pypy/tool/gcc_cache.py Thu Oct 23 12:32:04 2008 @@ -1,8 +1,7 @@ from pypy.tool.autopath import pypydir -from pypy.translator.tool.cbuild import build_executable +from pypy.translator.platform import platform, CompilationError from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.translator.tool.cbuild import CompilationError from pypy.tool.compat import md5 import py @@ -20,9 +19,9 @@ try: return path.read() except py.error.Error: - result = eci.platform.execute(build_executable(c_files, eci)) - path.write(result) - return result + result = platform.execute(platform.compile(c_files, eci)) + path.write(result.out) + return result.out def try_compile_cache(c_files, eci): path = cache_file_path(c_files, eci, 'try_compile_cache') @@ -32,7 +31,7 @@ data = '' if not (data.startswith('True') or data.startswith('FAIL\n')): try: - build_executable(c_files, eci) + platform.compile(c_files, eci) data = 'True' except CompilationError, e: data = 'FAIL\n%s\n' % (e,) @@ -42,4 +41,4 @@ else: assert data.startswith('FAIL\n') msg = data[len('FAIL\n'):] - raise CompilationError(msg.strip()) + raise CompilationError(msg.strip(), '') Modified: pypy/trunk/pypy/tool/test/test_gcc_cache.py ============================================================================== --- pypy/trunk/pypy/tool/test/test_gcc_cache.py (original) +++ pypy/trunk/pypy/tool/test/test_gcc_cache.py Thu Oct 23 12:32:04 2008 @@ -24,7 +24,8 @@ path = cache_file_path([f], eci, 'build_executable_cache') if path.check(): path.remove() - assert build_executable_cache([f], eci) == "3\n" + res = build_executable_cache([f], eci) + assert res == "3\n" assert build_executable_cache([f], eci) == "3\n" eci2 = ExternalCompilationInfo(include_dirs=[str(dir2)]) assert build_executable_cache([f], eci2) == "42\n" Modified: pypy/trunk/pypy/translator/c/genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/genc.py (original) +++ pypy/trunk/pypy/translator/c/genc.py Thu Oct 23 12:32:04 2008 @@ -6,10 +6,7 @@ from pypy.translator.c.extfunc import pre_include_code_lines from pypy.translator.llsupport.wrapper import new_wrapper from pypy.translator.gensupp import uniquemodulename, NameManager -from pypy.translator.tool.cbuild import so_ext, ExternalCompilationInfo -from pypy.translator.tool.cbuild import compile_c_module -from pypy.translator.tool.cbuild import CCompiler, ProfOpt -from pypy.translator.tool.cbuild import import_module_from_directory +from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator.tool.cbuild import check_under_under_thread from pypy.rpython.lltypesystem import lltype from pypy.tool.udir import udir @@ -18,6 +15,89 @@ from pypy.rpython.typesystem import getfunctionptr from pypy.translator.c import gc +def import_module_from_directory(dir, modname): + file, pathname, description = imp.find_module(modname, [str(dir)]) + try: + mod = imp.load_module(modname, file, pathname, description) + finally: + if file: + file.close() + return mod + +class ProfOpt(object): + #XXX assuming gcc style flags for now + name = "profopt" + + def __init__(self, compiler): + self.compiler = compiler + + def first(self): + platform = self.compiler.platform + if platform.name == 'darwin': + # XXX incredible hack for darwin + cfiles = self.compiler.cfiles + STR = '/*--no-profiling-for-this-file!--*/' + no_prof = [] + prof = [] + for cfile in self.compiler.cfiles: + if STR in cfile.read(): + no_prof.append(cfile) + else: + prof.append(cfile) + p_eci = self.compiler.eci.merge( + ExternalCompilationInfo(compile_extra=['-fprofile-generate'], + link_extra=['-fprofile-generate'])) + ofiles = platform._compile_o_files(prof, p_eci) + _, eci = self.compiler.eci.get_module_files() + ofiles += platform._compile_o_files(no_prof, eci) + return platform._finish_linking(ofiles, p_eci, None, True) + else: + return self.build('-fprofile-generate') + + def probe(self, exe, args): + # 'args' is a single string typically containing spaces + # and quotes, which represents several arguments. + self.compiler.platform.execute(exe, args) + + def after(self): + return self.build('-fprofile-use') + + def build(self, option): + eci = ExternalCompilationInfo(compile_extra=[option], + link_extra=[option]) + return self.compiler._build(eci) + +class CCompilerDriver(object): + def __init__(self, platform, cfiles, eci, outputfilename=None, + profbased=False): + # XXX config might contain additional link and compile options. + # We need to fish for it somehow. + self.platform = platform + self.cfiles = cfiles + self.eci = eci + self.outputfilename = outputfilename + self.profbased = profbased + + def _build(self, eci=ExternalCompilationInfo()): + return self.platform.compile(self.cfiles, self.eci.merge(eci), + outputfilename=self.outputfilename) + + def build(self): + if self.profbased: + return self._do_profbased() + return self._build() + + def _do_profbased(self): + ProfDriver, args = self.profbased + profdrv = ProfDriver(self) + dolog = getattr(log, profdrv.name) + dolog(args) + exename = profdrv.first() + dolog('Gathering profile data from: %s %s' % ( + str(exename), args)) + profdrv.probe(exename, args) + return profdrv.after() + class CBuilder(object): c_source_filename = None _compiled = False @@ -32,7 +112,16 @@ self.gcpolicy = gcpolicy # for tests only, e.g. rpython/memory/ if gcpolicy is not None and gcpolicy.requires_stackless: config.translation.stackless = True - self.eci = ExternalCompilationInfo() + self.eci = self.get_eci() + + def get_eci(self): + from distutils import sysconfig + python_inc = sysconfig.get_python_inc() # XXX refactor remaining dependencies + # like obmalloc into separately compilable + # modules etc. + pypy_include_dir = py.path.local(autopath.pypydir).join('translator', 'c') + include_dirs = [python_inc, pypy_include_dir] + return ExternalCompilationInfo(include_dirs=include_dirs) def build_database(self): translator = self.translator @@ -104,6 +193,19 @@ DEBUG_DEFINES = {'RPY_ASSERT': 1, 'RPY_LL_ASSERT': 1} + def generate_graphs_for_llinterp(self, db=None): + # prepare the graphs as when the source is generated, but without + # actually generating the source. + if db is None: + db = self.build_database() + graphs = db.all_graphs() + db.gctransformer.prepare_inline_helpers(graphs) + for node in db.containerlist: + if isinstance(node, FuncNode): + for funcgen in node.funcgens: + funcgen.patch_graph(copy_graph=False) + return db + def generate_source(self, db=None, defines={}): assert self.c_source_filename is None translator = self.translator @@ -124,48 +226,38 @@ if self.config.translation.sandbox: defines['RPY_SANDBOXED'] = 1 if CBuilder.have___thread is None: - CBuilder.have___thread = check_under_under_thread() + CBuilder.have___thread = self.translator.platform.check___thread() if not self.standalone: assert not self.config.translation.instrument - cfile, extra = gen_source(db, modulename, targetdir, self.eci, - defines = defines) + self.eci, cfile, extra = gen_source(db, modulename, targetdir, + self.eci, + defines = defines) else: if self.config.translation.instrument: defines['INSTRUMENT'] = 1 if CBuilder.have___thread: if not self.config.translation.no__thread: defines['USE___THREAD'] = 1 - # explicitely include python.h and exceptions.h - # XXX for now, we always include Python.h - from distutils import sysconfig - python_inc = sysconfig.get_python_inc() - pypy_include_dir = autopath.this_dir - self.eci = self.eci.merge(ExternalCompilationInfo( - include_dirs=[python_inc, pypy_include_dir], - )) - cfile, extra = gen_source_standalone(db, modulename, targetdir, + self.eci, cfile, extra = gen_source_standalone(db, modulename, + targetdir, self.eci, entrypointname = pfname, defines = defines) self.c_source_filename = py.path.local(cfile) - self.extrafiles = extra - if self.standalone: - self.gen_makefile(targetdir) + self.extrafiles = self.eventually_copy(extra) + self.gen_makefile(targetdir) return cfile - def generate_graphs_for_llinterp(self, db=None): - # prepare the graphs as when the source is generated, but without - # actually generating the source. - if db is None: - db = self.build_database() - graphs = db.all_graphs() - db.gctransformer.prepare_inline_helpers(graphs) - for node in db.containerlist: - if isinstance(node, FuncNode): - for funcgen in node.funcgens: - funcgen.patch_graph(copy_graph=False) - return db - + def eventually_copy(self, cfiles): + extrafiles = [] + for fn in cfiles: + fn = py.path.local(fn) + if not fn.relto(udir): + newname = self.targetdir.join(fn.basename) + fn.copy(newname) + fn = newname + extrafiles.append(fn) + return extrafiles class ModuleWithCleanup(object): def __init__(self, mod): @@ -173,7 +265,18 @@ def __getattr__(self, name): mod = self.__dict__['mod'] - return getattr(mod, name) + obj = getattr(mod, name) + 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.mod = mod + 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'] @@ -214,9 +317,8 @@ export_symbols.append('malloc_counters') extsymeci = ExternalCompilationInfo(export_symbols=export_symbols) self.eci = self.eci.merge(extsymeci) - compile_c_module([self.c_source_filename] + self.extrafiles, - self.c_source_filename.purebasename, self.eci, - tmpdir=self.c_source_filename.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): @@ -251,7 +353,7 @@ _rpython_startup = _lib.RPython_StartupCode _rpython_startup() -""" % {'so_name': self.c_source_filename.new(ext=so_ext), +""" % {'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) @@ -284,6 +386,9 @@ if isinstance(self._module, isolate.Isolate): isolate.close_isolate(self._module) + def gen_makefile(self, targetdir): + pass + class CStandaloneBuilder(CBuilder): standalone = True executable_name = None @@ -312,159 +417,75 @@ bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) - def getccompiler(self): - cc = self.config.translation.cc - # Copy extrafiles to target directory, if needed - extrafiles = [] - for fn in self.extrafiles: - fn = py.path.local(fn) - if not fn.relto(udir): - newname = self.targetdir.join(fn.basename) - fn.copy(newname) - fn = newname - extrafiles.append(fn) - - return CCompiler( - [self.c_source_filename] + extrafiles, - self.eci, compiler_exe = cc, profbased = self.getprofbased()) + def cmdexec(self, args=''): + assert self._compiled + res = self.translator.platform.execute(self.executable_name, args) + if res.returncode != 0: + raise Exception("Returned %d" % (res.returncode,)) + return res.out def compile(self): assert self.c_source_filename assert not self._compiled - compiler = self.getccompiler() if self.config.translation.gcrootfinder == "asmgcc": - # as we are gcc-only anyway, let's just use the Makefile. - cmdline = "make -C '%s'" % (self.targetdir,) - err = os.system(cmdline) - if err != 0: - raise OSError("failed (see output): " + cmdline) + self.translator.platform.execute_makefile(self.targetdir) else: - eci = self.eci.merge(ExternalCompilationInfo(includes= - [str(self.targetdir)])) - self.adaptflags(compiler) - compiler.build() - self.executable_name = str(compiler.outputfilename) + compiler = CCompilerDriver(self.translator.platform, + [self.c_source_filename] + self.extrafiles, + self.eci, profbased=self.getprofbased()) + self.executable_name = compiler.build() + assert self.executable_name self._compiled = True return self.executable_name - def cmdexec(self, args=''): - assert self._compiled - return py.process.cmdexec('"%s" %s' % (self.executable_name, args)) - - def adaptflags(self, compiler): - if sys.platform == 'darwin': - compiler.compile_extra.append('-mdynamic-no-pic') - if sys.platform == 'sunos5': - compiler.link_extra.append("-lrt") - if self.config.translation.compilerflags: - compiler.compile_extra.append(self.config.translation.compilerflags) - if self.config.translation.linkerflags: - compiler.link_extra.append(self.config.translation.linkerflags) - def gen_makefile(self, targetdir): - def write_list(lst, prefix): - for i, fn in enumerate(lst): - print >> f, prefix, fn, - if i < len(lst)-1: - print >> f, '\\' - else: - print >> f - prefix = ' ' * len(prefix) - - self.eci = self.eci.merge(ExternalCompilationInfo( - includes=['.', str(self.targetdir)])) - compiler = self.getccompiler() - - self.adaptflags(compiler) - assert self.config.translation.gcrootfinder != "llvmgc" - cfiles = [] - ofiles = [] - gcmapfiles = [] - for fn in compiler.cfilenames: - fn = py.path.local(fn) - if fn.dirpath() == targetdir: - name = fn.basename - else: - assert fn.dirpath().dirpath() == udir - name = '../' + fn.relto(udir) - - name = name.replace("\\", "/") - cfiles.append(name) - if self.config.translation.gcrootfinder == "asmgcc": - ofiles.append(name[:-2] + '.s') - gcmapfiles.append(name[:-2] + '.gcmap') - else: - ofiles.append(name[:-2] + '.o') - - if self.config.translation.cc: - cc = self.config.translation.cc - else: - cc = self.eci.platform.get_compiler() - if cc is None: - cc = 'gcc' - make_no_prof = '' + cfiles = [self.c_source_filename] + self.extrafiles + mk = self.translator.platform.gen_makefile(cfiles, self.eci, + path=targetdir) if self.has_profopt(): profopt = self.config.translation.profopt - default_target = 'profopt' - # XXX horrible workaround for a bug of profiling in gcc on - # OS X with functions containing a direct call to fork() - non_profilable = [] - assert len(compiler.cfilenames) == len(ofiles) - for fn, oname in zip(compiler.cfilenames, ofiles): - fn = py.path.local(fn) - if '/*--no-profiling-for-this-file!--*/' in fn.read(): - non_profilable.append(oname) - if non_profilable: - make_no_prof = '$(MAKE) %s' % (' '.join(non_profilable),) - else: - profopt = '' - default_target = '$(TARGET)' - - f = targetdir.join('Makefile').open('w') - print >> f, '# automatically generated Makefile' - print >> f - print >> f, 'PYPYDIR =', autopath.pypydir - print >> f - print >> f, 'TARGET =', py.path.local(compiler.outputfilename).basename - print >> f - print >> f, 'DEFAULT_TARGET =', default_target - print >> f - write_list(cfiles, 'SOURCES =') - print >> f - if self.config.translation.gcrootfinder == "asmgcc": - write_list(ofiles, 'ASMFILES =') - write_list(gcmapfiles, 'GCMAPFILES =') - print >> f, 'OBJECTS = $(ASMFILES) gcmaptable.s' - else: - print >> f, 'GCMAPFILES =' - write_list(ofiles, 'OBJECTS =') - print >> f - def makerel(path): - rel = py.path.local(path).relto(py.path.local(autopath.pypydir)) - if rel: - return os.path.join('$(PYPYDIR)', rel) - else: - return path - args = ['-l'+libname for libname in self.eci.libraries] - print >> f, 'LIBS =', ' '.join(args) - args = ['-L'+makerel(path) for path in self.eci.library_dirs] - print >> f, 'LIBDIRS =', ' '.join(args) - args = ['-I'+makerel(path) for path in self.eci.include_dirs] - write_list(args, 'INCLUDEDIRS =') - print >> f - print >> f, 'CFLAGS =', ' '.join(compiler.compile_extra) - print >> f, 'LDFLAGS =', ' '.join(compiler.link_extra) - if self.config.translation.thread: - print >> f, 'TFLAGS = ' + '-pthread' - else: - print >> f, 'TFLAGS = ' + '' - print >> f, 'PROFOPT = ' + profopt - print >> f, 'MAKENOPROF = ' + make_no_prof - print >> f, 'CC = ' + cc - print >> f - print >> f, MAKEFILE.strip() - f.close() - + mk.definition('ABS_TARGET', '$(shell python -c "import sys,os; print os.path.abspath(sys.argv[1])" $(TARGET))') + mk.definition('DEFAULT_TARGET', 'profopt') + mk.definition('PROFOPT', profopt) + + rules = [ + ('clean', '', 'rm -f $(OBJECTS) $(TARGET) $(GCMAPFILES) *.gc?? ../module_cache/*.gc??'), + ('clean_noprof', '', 'rm -f $(OBJECTS) $(TARGET) $(GCMAPFILES)'), + ('debug', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT" $(TARGET)'), + ('debug_exc', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DDO_LOG_EXC" $(TARGET)'), + ('debug_mem', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DTRIVIAL_MALLOC_DEBUG" $(TARGET)'), + ('no_obmalloc', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DNO_OBMALLOC" $(TARGET)'), + ('linuxmemchk', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DLINUXMEMCHK" $(TARGET)'), + ('llsafer', '', '$(MAKE) CFLAGS="-O2 -DRPY_LL_ASSERT" $(TARGET)'), + ('lldebug', '', '$(MAKE) CFLAGS="-g -DRPY_ASSERT -DRPY_LL_ASSERT" $(TARGET)'), + ('profile', '', '$(MAKE) CFLAGS="-g -pg $(CFLAGS)" LDFLAGS="-pg $(LDFLAGS)" $(TARGET)'), + ] + if self.has_profopt(): + rules.append( + ('profopt', '', [ + '$(MAKENOPROF)', + '$(MAKE) CFLAGS="-fprofile-generate $(CFLAGS)" LDFLAGS="-fprofile-generate $(LDFLAGS)" $(TARGET)', + 'cd $(PYPYDIR)/translator/goal && $(ABS_TARGET) $(PROFOPT)', + '$(MAKE) clean_noprof', + '$(MAKE) CFLAGS="-fprofile-use $(CFLAGS)" LDFLAGS="-fprofile-use $(LDFLAGS)" $(TARGET)'])) + for rule in rules: + mk.rule(*rule) + + if self.config.translation.gcrootfinder == 'asmgcc': + ofiles = ['%s.s' % (cfile[:-2],) for cfile in mk.cfiles] + gcmapfiles = ['%s.gcmap' % (cfile[:-2],) for cfile in mk.cfiles] + mk.definition('ASMFILES', ofiles) + mk.definition('GCMAPFILES', gcmapfiles) + mk.definition('OBJECTS', '$(ASMFILES) gcmaptable.s') + mk.rule('%.s', '%.c', '$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS)') + mk.rule('%.gcmap', '%.s', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $@ || (rm -f $@ && exit 1)') + mk.rule('gcmaptable.s', '$(GCMAPFILES)', '$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@ || (rm -f $@ && exit 1)') + + mk.write() + #self.translator.platform, + # , + # self.eci, profbased=self.getprofbased() + self.executable_name = mk.exe_name # ____________________________________________________________ @@ -788,8 +809,8 @@ fi.close() eci = eci.convert_sources_to_files(being_main=True) - return filename, sg.getextrafiles() + list(eci.separate_module_files) - + files, eci = eci.get_module_files() + return eci, filename, sg.getextrafiles() + list(files) def gen_source(database, modulename, targetdir, eci, defines={}): assert not database.standalone @@ -837,100 +858,6 @@ gen_startupcode(f, database) f.close() - # - # Generate a setup.py while we're at it - # - pypy_include_dir = autopath.this_dir - f = targetdir.join('setup.py').open('w') - include_dirs = eci.include_dirs - library_dirs = eci.library_dirs - libraries = eci.libraries - f.write(SETUP_PY % locals()) - f.close() eci = eci.convert_sources_to_files(being_main=True) - - return filename, sg.getextrafiles() + list(eci.separate_module_files) - - -SETUP_PY = ''' -from distutils.core import setup -from distutils.extension import Extension -from distutils.ccompiler import get_default_compiler - -PYPY_INCLUDE_DIR = %(pypy_include_dir)r - -extra_compile_args = [] -if get_default_compiler() == "unix": - extra_compile_args.extend(["-Wno-unused-label", - "-Wno-unused-variable"]) - -setup(name="%(modulename)s", - ext_modules = [Extension(name = "%(modulename)s", - sources = ["%(modulename)s.c"], - extra_compile_args = extra_compile_args, - include_dirs = (PYPY_INCLUDE_DIR,) + %(include_dirs)r, - library_dirs = %(library_dirs)r, - libraries = %(libraries)r)]) -''' - -MAKEFILE = ''' - -all: $(DEFAULT_TARGET) - -$(TARGET): $(OBJECTS) -\t$(CC) $(LDFLAGS) $(TFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS) - -# -frandom-seed is only to try to be as reproducable as possible - -%.o: %.c -\t$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -c $< $(INCLUDEDIRS) - -%.s: %.c -\t$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS) - -%.gcmap: %.s -\t$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $@ || (rm -f $@ && exit 1) - -gcmaptable.s: $(GCMAPFILES) -\t$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@ || (rm -f $@ && exit 1) - -clean: -\trm -f $(OBJECTS) $(TARGET) $(GCMAPFILES) *.gc?? ../module_cache/*.gc?? - -clean_noprof: -\trm -f $(OBJECTS) $(TARGET) $(GCMAPFILES) - -debug: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT" $(TARGET) - -debug_exc: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DDO_LOG_EXC" $(TARGET) - -debug_mem: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DTRIVIAL_MALLOC_DEBUG" $(TARGET) - -no_obmalloc: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DNO_OBMALLOC" $(TARGET) - -linuxmemchk: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DLINUXMEMCHK" $(TARGET) - -llsafer: -\t$(MAKE) CFLAGS="-O2 -DRPY_LL_ASSERT" $(TARGET) - -lldebug: -\t$(MAKE) CFLAGS="-g -DRPY_ASSERT -DRPY_LL_ASSERT" $(TARGET) - -profile: -\t$(MAKE) CFLAGS="-g -pg $(CFLAGS)" LDFLAGS="-pg $(LDFLAGS)" $(TARGET) - -# it seems that GNU Make < 3.81 has no function $(abspath) -ABS_TARGET = $(shell python -c "import sys,os; print os.path.abspath(sys.argv[1])" $(TARGET)) - -profopt: -\t$(MAKENOPROF) # these files must be compiled without profiling -\t$(MAKE) CFLAGS="-fprofile-generate $(CFLAGS)" LDFLAGS="-fprofile-generate $(LDFLAGS)" $(TARGET) -\tcd $(PYPYDIR)/translator/goal && $(ABS_TARGET) $(PROFOPT) -\t$(MAKE) clean_noprof -\t$(MAKE) CFLAGS="-fprofile-use $(CFLAGS)" LDFLAGS="-fprofile-use $(LDFLAGS)" $(TARGET) -''' + files, eci = eci.get_module_files() + return eci, filename, sg.getextrafiles() + list(files) Modified: pypy/trunk/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/g_include.h (original) +++ pypy/trunk/pypy/translator/c/src/g_include.h Thu Oct 23 12:32:04 2008 @@ -60,6 +60,7 @@ #endif #ifdef PYPY_STANDALONE +# include "src/allocator.h" # include "src/main.h" #endif Modified: pypy/trunk/pypy/translator/c/src/signals.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/signals.h (original) +++ pypy/trunk/pypy/translator/c/src/signals.h Thu Oct 23 12:32:04 2008 @@ -4,7 +4,21 @@ #ifndef _PYPY_SIGNALS_H #define _PYPY_SIGNALS_H -#include "Python.h" /* XXX for LONG_MIN */ +#include + +#ifndef LONG_MAX +#if SIZEOF_LONG == 4 +#define LONG_MAX 0X7FFFFFFFL +#elif SIZEOF_LONG == 8 +#define LONG_MAX 0X7FFFFFFFFFFFFFFFL +#else +#error "could not set LONG_MAX in pyport.h" +#endif +#endif + +#ifndef LONG_MIN +#define LONG_MIN (-LONG_MAX-1) +#endif #include Modified: pypy/trunk/pypy/translator/c/src/standalone.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/standalone.h (original) +++ pypy/trunk/pypy/translator/c/src/standalone.h Thu Oct 23 12:32:04 2008 @@ -4,32 +4,7 @@ #include #include -#ifndef PYPY_NOT_MAIN_FILE -#ifdef AVR - #ifndef NO_OBMALLOC - #define NO_OBMALLOC - #endif -#endif - -#if defined(TRIVIAL_MALLOC_DEBUG) - void *PyObject_Malloc(size_t n) { return malloc(n); } - void *PyObject_Realloc(void *p, size_t n) { return realloc(p, n); } - void PyObject_Free(void *p) { if (p) { *((int*)p) = 0xDDDDDDDD; } free(p); } - -#elif defined(LINUXMEMCHK) -# include "linuxmemchk.c" - -#elif defined(NO_OBMALLOC) - void *PyObject_Malloc(size_t n) { return malloc(n); } - void *PyObject_Realloc(void *p, size_t n) { return realloc(p, n); } - void PyObject_Free(void *p) { free(p); } - -#else -# ifndef WITH_PYMALLOC -# define WITH_PYMALLOC -# endif -# include "obmalloc.c" - -#endif - -#endif +/* allocation functions prototypes */ +void *PyObject_Malloc(size_t n); +void *PyObject_Realloc(void *p, size_t n); +void PyObject_Free(void *p); Modified: pypy/trunk/pypy/translator/c/src/thread_nt.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/thread_nt.h (original) +++ pypy/trunk/pypy/translator/c/src/thread_nt.h Thu Oct 23 12:32:04 2008 @@ -234,6 +234,7 @@ /* Thread-local storage */ #define RPyThreadTLS DWORD +#define __thread __declspec(thread) char *RPyThreadTLS_Create(RPyThreadTLS *result) { Modified: pypy/trunk/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_boehm.py (original) +++ pypy/trunk/pypy/translator/c/test/test_boehm.py Thu Oct 23 12:32:04 2008 @@ -2,12 +2,12 @@ from pypy.translator.translator import TranslationContext from pypy.rpython.lltypesystem import lltype from pypy.rpython.memory.test import snippet -from pypy.translator.tool.cbuild import check_boehm_presence +from pypy.rpython.tool.rffi_platform import check_boehm from pypy.translator.c.genc import CExtModuleBuilder from pypy import conftest def setup_module(mod): - if not check_boehm_presence(): + if not check_boehm(): py.test.skip("Boehm GC not present") class AbstractGCTestClass(object): Modified: pypy/trunk/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/trunk/pypy/translator/c/test/test_extfunc.py Thu Oct 23 12:32:04 2008 @@ -382,97 +382,6 @@ res = f(1.5) assert eval(res) == 1.5 -def test_lock(): - py.test.skip("XXX out-of-date, and should not be here") - import thread - import pypy.module.thread.rpython.exttable # for declare()/declaretype() - def fn(): - l = thread.allocate_lock() - ok1 = l.acquire(True) - ok2 = l.acquire(False) - l.release() - ok2_and_a_half = False - try: - l.release() - except thread.error: - ok2_and_a_half = True - ok3 = l.acquire(False) - return ok1 and not ok2 and ok2_and_a_half and ok3 - f = compile(fn, []) - res = f() - assert res is True - -def test_simple_start_new_thread(): - py.test.skip("XXX out-of-date, and should not be here") - import thread - import pypy.module.thread.rpython.exttable # for declare()/declaretype() - class Arg: - pass - def mythreadedfunction(arg): - assert arg.value == 42 - def myotherthreadedfunction(arg): - assert arg.value == 43 - a42 = Arg() - a42.value = 42 - a43 = Arg() - a43.value = 43 - def fn(i): - thread.start_new_thread(mythreadedfunction, (a42,)) - thread.start_new_thread(myotherthreadedfunction, (a43,)) - if i == 1: - x = mythreadedfunction - a = a42 - else: - x = myotherthreadedfunction - a = a43 - thread.start_new_thread(x, (a,)) - return 42 - f = compile(fn, [int]) - res = f(1) - assert res == 42 - -def test_start_new_thread(): - py.test.skip("XXX out-of-date, and should not be here") - import thread - import pypy.module.thread.rpython.exttable # for declare()/declaretype() - class Arg: - pass - a = Arg() - a.x = 5 - a.lock = thread.allocate_lock() - def mythreadedfunction(arg): - arg.x += 37 - arg.myident = thread.get_ident() - arg.lock.release() - def fn(): - a.lock.acquire(True) - ident = thread.start_new_thread(mythreadedfunction, (a,)) - assert ident != thread.get_ident() - a.lock.acquire(True) # wait for the thread to finish - assert a.myident == ident - return a.x - f = compile(fn, []) - res = f() - assert res == 42 - -def test_prebuilt_lock(): - py.test.skip("XXX out-of-date, and should not be here") - import thread - import pypy.module.thread.rpython.exttable # for declare()/declaretype() - lock0 = thread.allocate_lock() - lock1 = thread.allocate_lock() - lock1.acquire() - def fn(i): - lock = [lock0, lock1][i] - ok = lock.acquire(False) - if ok: lock.release() - return ok - f = compile(fn, [int]) - res = f(0) - assert res is True - res = f(1) - assert res is False - def test_os_unlink(): tmpfile = str(udir.join('test_os_path_exists.TMP')) def fn(): @@ -845,10 +754,9 @@ py.test.raises(OSError, "func()") def test_execve(): - import py; py.test.skip("in-progress") filename = str(udir.join('test_execve.txt')) + progname = sys.executable def does_stuff(): - progname = str(sys.executable) l = [] l.append(progname) l.append("-c") Modified: pypy/trunk/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_genc.py (original) +++ pypy/trunk/pypy/translator/c/test/test_genc.py Thu Oct 23 12:32:04 2008 @@ -9,7 +9,6 @@ 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.tool.cbuild import make_module_from_c from pypy.translator.gensupp import uniquemodulename from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.interactive import Translation Modified: pypy/trunk/pypy/translator/c/test/test_rtagged.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_rtagged.py (original) +++ pypy/trunk/pypy/translator/c/test/test_rtagged.py Thu Oct 23 12:32:04 2008 @@ -69,7 +69,7 @@ def test_tagged_boehm(): t = Translation(entry_point, standalone=True, gc='boehm') try: - exename = t.compile_c() + exename = str(t.compile_c()) finally: if conftest.option.view: t.view() Modified: pypy/trunk/pypy/translator/c/test/test_stackless.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_stackless.py (original) +++ pypy/trunk/pypy/translator/c/test/test_stackless.py Thu Oct 23 12:32:04 2008 @@ -20,8 +20,8 @@ import py py.test.skip("stackless + refcounting doesn't work any more for now") elif cls.gcpolicy == "boehm": - from pypy.translator.tool.cbuild import check_boehm_presence - if not check_boehm_presence(): + from pypy.rpython.tool.rffi_platform import check_boehm + if not check_boehm(): py.test.skip("Boehm GC not present") def wrap_stackless_function(self, fn): Modified: pypy/trunk/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_standalone.py (original) +++ pypy/trunk/pypy/translator/c/test/test_standalone.py Thu Oct 23 12:32:04 2008 @@ -10,246 +10,259 @@ from pypy.tool.autopath import pypydir -def test_hello_world(): - def entry_point(argv): - os.write(1, "hello world\n") - argv = argv[1:] - os.write(1, "argument count: " + str(len(argv)) + "\n") - for s in argv: - os.write(1, " '" + str(s) + "'\n") - return 0 - - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('hi there') - assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') - -def test_print(): - def entry_point(argv): - print "hello simpler world" - argv = argv[1:] - print "argument count:", len(argv) - print "arguments:", argv - print "argument lengths:", - print [len(s) for s in argv] - return 0 - - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('hi there') - assert data.startswith('''hello simpler world\n''' - '''argument count: 2\n''' - '''arguments: [hi, there]\n''' - '''argument lengths: [2, 5]\n''') - # NB. RPython has only str, not repr, so str() on a list of strings - # gives the strings unquoted in the list - -def test_counters(): - from pypy.rpython.lltypesystem import lltype - from pypy.rpython.lltypesystem.lloperation import llop - def entry_point(argv): - llop.instrument_count(lltype.Void, 'test', 2) - llop.instrument_count(lltype.Void, 'test', 1) - llop.instrument_count(lltype.Void, 'test', 1) - llop.instrument_count(lltype.Void, 'test', 2) - llop.instrument_count(lltype.Void, 'test', 1) - return 0 - t = TranslationContext() - t.config.translation.instrument = True - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - - cbuilder = CStandaloneBuilder(t, entry_point, config=t.config) # xxx - cbuilder.generate_source() - cbuilder.compile() - - counters_fname = udir.join("_counters_") - os.putenv('_INSTRUMENT_COUNTERS', str(counters_fname)) - try: - data = cbuilder.cmdexec() - finally: - os.unsetenv('_INSTRUMENT_COUNTERS') - - f = counters_fname.open('rb') - counters_data = f.read() - f.close() - - import struct - counters = struct.unpack("LLL", counters_data) - - assert counters == (0,3,2) - -def test_prof_inline(): - if sys.platform == 'win32': - py.test.skip("instrumentation support is unix only for now") - def add(a,b): - return a + b - b + b - b + b - b + b - b + b - b + b - b + b - def entry_point(argv): - tot = 0 - x = int(argv[1]) - while x > 0: - tot = add(tot, x) - x -= 1 - os.write(1, str(tot)) - return 0 - from pypy.translator.interactive import Translation - t = Translation(entry_point, backend='c', standalone=True) - # 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) - # counters - t.backendopt(inline_threshold=all.INLINE_THRESHOLD_FOR_TEST*0.5, - profile_based_inline="500") - exe = t.compile() - out = py.process.cmdexec("%s 500" % exe) - assert int(out) == 500*501/2 +class TestStandalone(object): + config = None -def test_frexp(): - import math - def entry_point(argv): - m, e = math.frexp(0) - x, y = math.frexp(0) - print m, x - return 0 - - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('hi there') - assert map(float, data.split()) == [0.0, 0.0] - -def test_profopt(): - def add(a,b): - return a + b - b + b - b + b - b + b - b + b - b + b - b + b - def entry_point(argv): - tot = 0 - x = int(argv[1]) - while x > 0: - tot = add(tot, x) - x -= 1 - os.write(1, str(tot)) - 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="") - # 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="", - noprofopt=True) - # no counters - t.backendopt() - exe = t.compile() - out = py.process.cmdexec("%s 500" % exe) - assert int(out) == 500*501/2 - -def test_standalone_large_files(): - from pypy.module.posix.test.test_posix2 import need_sparse_files - need_sparse_files() - filename = str(udir.join('test_standalone_largefile')) - r4800000000 = r_longlong(4800000000L) - def entry_point(argv): - fd = os.open(filename, os.O_RDWR | os.O_CREAT, 0644) - os.lseek(fd, r4800000000, 0) - os.write(fd, "$") - newpos = os.lseek(fd, 0, 1) - if newpos == r4800000000 + 1: - print "OK" - else: - print "BAD POS" - os.close(fd) - return 0 - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('hi there') - assert data.strip() == "OK" - -def test_separate_files(): - # One file in translator/c/src - fname = py.path.local(pypydir).join( - 'translator', 'c', 'src', 'll_strtod.h') - - # One file in (another) subdir of the temp directory - dirname = udir.join("test_dir").ensure(dir=1) - fname2 = dirname.join("test_genc.c") - fname2.write(""" - void f() { - LL_strtod_formatd("%5f", 12.3); - }""") - - files = [fname, fname2] - - def entry_point(argv): - return 0 - - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - - cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.eci = cbuilder.eci.merge( - ExternalCompilationInfo(separate_module_files=files)) - cbuilder.generate_source() - - makefile = udir.join(cbuilder.modulename, 'Makefile').read() - - # generated files are compiled in the same directory - assert " ../test_dir/test_genc.c" in makefile - assert " ../test_dir/test_genc.o" in makefile - - # 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.o" in makefile - -def test_cross_compilation(): - from pypy.rlib.pyplatform import Platform - from pypy.config.translationoption import set_platform - - class X(Platform): - def get_compiler(self): - return 'x' - - def entry_point(argv): - return 0 - - t = TranslationContext() - t.buildannotator().build_types(entry_point, [s_list_of_strings]) - t.buildrtyper().specialize() - - set_platform(t.config, X()) - try: - eci = ExternalCompilationInfo(platform=X()) + def test_hello_world(self): + def entry_point(argv): + os.write(1, "hello world\n") + argv = argv[1:] + os.write(1, "argument count: " + str(len(argv)) + "\n") + for s in argv: + os.write(1, " '" + str(s) + "'\n") + return 0 + + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() cbuilder = CStandaloneBuilder(t, entry_point, t.config) cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('hi there') + assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') + + def test_print(self): + def entry_point(argv): + print "hello simpler world" + argv = argv[1:] + print "argument count:", len(argv) + print "arguments:", argv + print "argument lengths:", + print [len(s) for s in argv] + return 0 + + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() + + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('hi there') + assert data.startswith('''hello simpler world\n''' + '''argument count: 2\n''' + '''arguments: [hi, there]\n''' + '''argument lengths: [2, 5]\n''') + # NB. RPython has only str, not repr, so str() on a list of strings + # gives the strings unquoted in the list + + def test_counters(self): + from pypy.rpython.lltypesystem import lltype + from pypy.rpython.lltypesystem.lloperation import llop + def entry_point(argv): + llop.instrument_count(lltype.Void, 'test', 2) + llop.instrument_count(lltype.Void, 'test', 1) + llop.instrument_count(lltype.Void, 'test', 1) + llop.instrument_count(lltype.Void, 'test', 2) + llop.instrument_count(lltype.Void, 'test', 1) + return 0 + t = TranslationContext(self.config) + t.config.translation.instrument = True + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() + + cbuilder = CStandaloneBuilder(t, entry_point, config=t.config) # xxx + cbuilder.generate_source() + cbuilder.compile() + + counters_fname = udir.join("_counters_") + os.putenv('_INSTRUMENT_COUNTERS', str(counters_fname)) + try: + data = cbuilder.cmdexec() + finally: + os.unsetenv('_INSTRUMENT_COUNTERS') + + f = counters_fname.open('rb') + counters_data = f.read() + f.close() + + import struct + counters = struct.unpack("LLL", counters_data) + + assert counters == (0,3,2) + + def test_prof_inline(self): + if sys.platform == 'win32': + py.test.skip("instrumentation support is unix only for now") + def add(a,b): + return a + b - b + b - b + b - b + b - b + b - b + b - b + b + def entry_point(argv): + tot = 0 + x = int(argv[1]) + while x > 0: + tot = add(tot, x) + x -= 1 + os.write(1, str(tot)) + return 0 + from pypy.translator.interactive import Translation + t = Translation(entry_point, backend='c', standalone=True) + # 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) + # counters + t.backendopt(inline_threshold=all.INLINE_THRESHOLD_FOR_TEST*0.5, + profile_based_inline="500") + exe = t.compile() + out = py.process.cmdexec("%s 500" % exe) + assert int(out) == 500*501/2 + + def test_frexp(self): + import math + def entry_point(argv): + m, e = math.frexp(0) + x, y = math.frexp(0) + print m, x + return 0 + + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() + + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('hi there') + assert map(float, data.split()) == [0.0, 0.0] + + def test_profopt(self): + def add(a,b): + return a + b - b + b - b + b - b + b - b + b - b + b - b + b + def entry_point(argv): + tot = 0 + x = int(argv[1]) + while x > 0: + tot = add(tot, x) + x -= 1 + os.write(1, str(tot)) + 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="") + # 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="", + noprofopt=True) + # no counters + t.backendopt() + exe = t.compile() + out = py.process.cmdexec("%s 500" % exe) + assert int(out) == 500*501/2 + + def test_profopt_mac_osx_bug(self): + def entry_point(argv): + import os + pid = os.fork() + if pid: + os.waitpid(pid, 0) + else: + os._exit(0) + 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="") + # no counters + t.backendopt() + exe = t.compile() + #py.process.cmdexec(exe) + t = Translation(entry_point, backend='c', standalone=True, profopt="", + noprofopt=True) + # no counters + t.backendopt() + exe = t.compile() + #py.process.cmdexec(exe) + + def test_standalone_large_files(self): + from pypy.module.posix.test.test_posix2 import need_sparse_files + need_sparse_files() + filename = str(udir.join('test_standalone_largefile')) + r4800000000 = r_longlong(4800000000L) + def entry_point(argv): + fd = os.open(filename, os.O_RDWR | os.O_CREAT, 0644) + os.lseek(fd, r4800000000, 0) + os.write(fd, "$") + newpos = os.lseek(fd, 0, 1) + if newpos == r4800000000 + 1: + print "OK" + else: + print "BAD POS" + os.close(fd) + return 0 + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('hi there') + assert data.strip() == "OK" + + def test_separate_files(self): + # One file in translator/c/src + fname = py.path.local(pypydir).join( + 'translator', 'c', 'src', 'll_strtod.h') + + # One file in (another) subdir of the temp directory + dirname = udir.join("test_dir").ensure(dir=1) + fname2 = dirname.join("test_genc.c") + fname2.write(""" + void f() { + LL_strtod_formatd("%5f", 12.3); + }""") + + files = [fname, fname2] + + def entry_point(argv): + return 0 + + t = TranslationContext(self.config) + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() + + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.eci = cbuilder.eci.merge( + ExternalCompilationInfo(separate_module_files=files)) + cbuilder.generate_source() makefile = udir.join(cbuilder.modulename, 'Makefile').read() - m = re.search('^CC\s*=\s*x$', makefile) - finally: - set_platform(t.config, Platform()) + # generated files are compiled in the same directory + assert " ../test_dir/test_genc.c" in makefile + assert " ../test_dir/test_genc.o" in makefile + + # 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.o" in makefile + +class TestMaemo(TestStandalone): + def setup_class(cls): + from pypy.translator.platform.maemo import check_scratchbox + check_scratchbox() + from pypy.config.pypyoption import get_pypy_config + config = get_pypy_config(translating=True) + config.translation.platform = 'maemo' + cls.config = config + + def test_profopt(self): + py.test.skip("Unsupported") + + def test_prof_inline(self): + py.test.skip("Unsupported") Modified: pypy/trunk/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_typed.py (original) +++ pypy/trunk/pypy/translator/c/test/test_typed.py Thu Oct 23 12:32:04 2008 @@ -10,11 +10,6 @@ from pypy.translator.translator import TranslationContext from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask -# XXX this tries to make compiling faster for full-scale testing -from pypy.translator.tool import cbuild -cbuild.enable_fast_compilation() - - class CompilationTestCase: def annotatefunc(self, func, argtypes=None): Modified: pypy/trunk/pypy/translator/driver.py ============================================================================== --- pypy/trunk/pypy/translator/driver.py (original) +++ pypy/trunk/pypy/translator/driver.py Thu Oct 23 12:32:04 2008 @@ -53,13 +53,12 @@ self.compiler = compiler def first(self): - self.compiler._build() + return self.compiler._build() def probe(self, exe, args): - from py.compat import subprocess env = os.environ.copy() env['_INSTRUMENT_COUNTERS'] = str(self.datafile) - subprocess.call("'%s' %s" % (exe, args), env=env, shell=True) + self.compiler.platform.execute(exe, args, env=env) def after(self): # xxx @@ -276,7 +275,12 @@ self.proceed('compile') assert False, 'we should not get here' finally: - self.timer.end_event(goal) + try: + self.timer.end_event(goal) + except (KeyboardInterrupt, SystemExit): + raise + except: + pass return res def task_annotate(self): @@ -453,13 +457,10 @@ def possibly_check_for_boehm(self): if self.config.translation.gc == "boehm": - from pypy.translator.tool.cbuild import check_boehm_presence - from pypy.translator.tool.cbuild import CompilationError - try: - check_boehm_presence(noerr=False) - except CompilationError, e: + from pypy.rpython.tool.rffi_platform import check_boehm + if not check_boehm(self.translator.platform): i = 'Boehm GC not installed. Try e.g. "translate.py --gc=hybrid"' - raise CompilationError('%s\n--------------------\n%s' % (e, i)) + raise Exception(i) def task_database_c(self): translator = self.translator @@ -506,13 +507,13 @@ newexename = self.exe_name % self.get_info() if '/' not in newexename and '\\' not in newexename: newexename = './' + newexename - return mkexename(newexename) + return mkexename(py.path.local(newexename)) def create_exe(self): if self.exe_name is not None: exename = mkexename(self.c_entryp) newexename = self.compute_exe_name() - shutil.copy(exename, newexename) + shutil.copy(str(exename), str(newexename)) self.c_entryp = newexename self.log.info("created: %s" % (self.c_entryp,)) @@ -858,5 +859,5 @@ def mkexename(name): if sys.platform == 'win32': - name = os.path.normpath(name + '.exe') + name = name.new(ext='exe') return name Modified: pypy/trunk/pypy/translator/goal/translate.py ============================================================================== --- pypy/trunk/pypy/translator/goal/translate.py (original) +++ pypy/trunk/pypy/translator/goal/translate.py Thu Oct 23 12:32:04 2008 @@ -52,9 +52,6 @@ ChoiceOption("opt", "optimization level", OPT_LEVELS, default=DEFAULT_OPT_LEVEL, cmdline="--opt -O"), - ChoiceOption("platform", - "target platform", ['host'] + PLATFORMS, default='host', - cmdline='--platform'), BoolOption("profile", "cProfile (to debug the speed of the translation process)", default=False, @@ -163,7 +160,7 @@ translating=True) # apply the platform settings - set_platform(config, translateconfig.platform) + set_platform(config) # apply the optimization level settings set_opt_level(config, translateconfig.opt) Modified: pypy/trunk/pypy/translator/sandbox/test/test_pypy_interact.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/test/test_pypy_interact.py (original) +++ pypy/trunk/pypy/translator/sandbox/test/test_pypy_interact.py Thu Oct 23 12:32:04 2008 @@ -66,7 +66,7 @@ def setup_module(mod): t = Translation(mini_pypy_like_entry_point, backend='c', standalone=True, sandbox=True) - mod.executable = t.compile() + mod.executable = str(t.compile()) def test_run(): Modified: pypy/trunk/pypy/translator/sandbox/test/test_sandbox.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/test/test_sandbox.py (original) +++ pypy/trunk/pypy/translator/sandbox/test/test_sandbox.py Thu Oct 23 12:32:04 2008 @@ -29,7 +29,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_os.ll_os_open", ("/tmp/foobar", os.O_RDONLY, 0777), 77) expect(f, g, "ll_os.ll_os_dup", (77,), 78) @@ -50,7 +50,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_os.ll_os_open", ("/tmp/foobar", os.O_RDONLY, 0777), 77) expect(f, g, "ll_os.ll_os_read", (77, 123), "he\x00llo") @@ -68,7 +68,7 @@ return 1 - y t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_os.ll_os_dup2", (34, 56), None) expect(f, g, "ll_os.ll_os_access", ("spam", 77), True) @@ -88,7 +88,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) st = os.stat_result((55, 0, 0, 0, 0, 0, 0x12380000007, 0, 0, 0)) expect(f, g, "ll_os.ll_os_stat", ("somewhere",), st, @@ -106,7 +106,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_time.ll_time_time", (), 3.141592) expect(f, g, "ll_os.ll_os_dup", (3141,), 3) @@ -124,7 +124,7 @@ return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) g, f = os.popen2(exe, "t", 0) expect(f, g, "ll_os.ll_os_stat", ("somewhere",), OSError(6321, "egg")) expect(f, g, "ll_os.ll_os_close", (6321,), None) @@ -138,7 +138,7 @@ def run(self, entry_point, args, expected): t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) from pypy.translator.sandbox.sandlib import SimpleIOSandboxedProc proc = SimpleIOSandboxedProc([exe] + args) output, error = proc.communicate() Modified: pypy/trunk/pypy/translator/sandbox/test/test_sandlib.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/test/test_sandlib.py (original) +++ pypy/trunk/pypy/translator/sandbox/test/test_sandlib.py Thu Oct 23 12:32:04 2008 @@ -47,7 +47,7 @@ os.close(fd) return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = MySandboxedProc([exe, 'x1', 'y2'], expected = [ ("open", ("/tmp/foobar", os.O_RDONLY, 0777), 77), @@ -69,7 +69,7 @@ s = rffi.str2charp(argv[n]); n = foobar(s); rffi.free_charp(s) return n t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = MySandboxedProc([exe, 'spam', 'egg'], expected = [ ("foobar", ("spam",), 2), @@ -93,7 +93,7 @@ print "The double is:", num * 2 return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = SimpleIOSandboxedProc([exe, 'x1', 'y2']) output, error = proc.communicate("21\n") @@ -111,7 +111,7 @@ print os.read(fd, 30) return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = SocketProc([exe]) output, error = proc.communicate("") @@ -125,7 +125,7 @@ os.close(e.errno) # nonsense, just to see outside return 0 t = Translation(entry_point, backend='c', standalone=True, sandbox=True) - exe = t.compile() + exe = str(t.compile()) proc = MySandboxedProc([exe], expected = [ ("open", ("/tmp/foobar", os.O_RDONLY, 0777), OSError(-42, "baz")), Modified: pypy/trunk/pypy/translator/test/test_geninterp.py ============================================================================== --- pypy/trunk/pypy/translator/test/test_geninterp.py (original) +++ pypy/trunk/pypy/translator/test/test_geninterp.py Thu Oct 23 12:32:04 2008 @@ -27,7 +27,6 @@ import py from pypy.tool.udir import udir from pypy.objspace.flow.model import * -from pypy.translator.tool.cbuild import make_module_from_c from pypy.translator.geninterplevel import translate_as_module from pypy.translator.test import snippet from pypy.interpreter.error import OperationError Modified: pypy/trunk/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/trunk/pypy/translator/tool/cbuild.py (original) +++ pypy/trunk/pypy/translator/tool/cbuild.py Thu Oct 23 12:32:04 2008 @@ -1,22 +1,16 @@ -import autopath - import os, sys, inspect, re, imp -from pypy.translator.tool import stdoutcapture -from pypy.tool.autopath import pypydir import py + +from pypy.tool.autopath import pypydir +from pypy.translator.platform import host from pypy.tool.ansi_print import ansi_log -log = py.log.Producer("cbuild") -py.log.setconsumer("cbuild", ansi_log) from pypy.tool.udir import udir -debug = 0 -CFLAGS = os.getenv("CFLAGS") -if CFLAGS: - CFLAGS = CFLAGS.split() -else: - CFLAGS = ['-O3'] +log = py.log.Producer("cbuild") +py.log.setconsumer("cbuild", ansi_log) + class ExternalCompilationInfo(object): @@ -89,8 +83,7 @@ assert isinstance(value, (list, tuple)) setattr(self, name, tuple(value)) if platform is None: - from pypy.rlib import pyplatform - platform = pyplatform.platform + from pypy.translator.platform import platform self.platform = platform def from_compiler_flags(cls, flags): @@ -255,418 +248,33 @@ d['separate_module_files'] += tuple(files) return ExternalCompilationInfo(**d) + def get_module_files(self): + d = self._copy_attributes() + files = d['separate_module_files'] + d['separate_module_files'] = () + return files, ExternalCompilationInfo(**d) + def compile_shared_lib(self): self = self.convert_sources_to_files() if not self.separate_module_files: return self - lib = compile_c_module([], 'externmod', self) + # find more or less unique name there + basepath = py.path.local(self.separate_module_files[0]).dirpath() + pth = basepath.join('externmod').new(ext=host.so_ext) + num = 0 + while pth.check(): + pth = basepath.join('externmod_%d' % (num,)).new(ext=host.so_ext) + num += 1 + lib = str(host.compile([], self, outputfilename=pth.purebasename, + standalone=False)) d = self._copy_attributes() d['libraries'] += (lib,) d['separate_module_files'] = () d['separate_module_sources'] = () return ExternalCompilationInfo(**d) -if sys.platform == 'win32': - so_ext = '.dll' -else: - so_ext = '.so' - -def compiler_command(): - # e.g. for tcc, you might set this to - # "tcc -shared -o %s.so %s.c" - return os.getenv('PYPY_CC') - -def enable_fast_compilation(): - if sys.platform == 'win32': - dash = '/' - else: - dash = '-' - from distutils import sysconfig - gcv = sysconfig.get_config_vars() - opt = gcv.get('OPT') # not always existent - if opt: - opt = re.sub('%sO\d+' % dash, '%sO0' % dash, opt) - else: - opt = '%sO0' % dash - gcv['OPT'] = opt - -def ensure_correct_math(): - if sys.platform != 'win32': - return # so far - from distutils import sysconfig - gcv = sysconfig.get_config_vars() - opt = gcv.get('OPT') # not always existent - if opt and '/Op' not in opt: - opt += '/Op' - gcv['OPT'] = opt - -def compile_c_module(cfiles, modbasename, eci, tmpdir=None): - #try: - # from distutils.log import set_threshold - # set_threshold(10000) - #except ImportError: - # print "ERROR IMPORTING" - # pass - cfiles = [py.path.local(f) for f in cfiles] - if tmpdir is None: - tmpdir = udir.join("module_cache").ensure(dir=1) - num = 0 - cfiles += eci.separate_module_files - include_dirs = list(eci.include_dirs) - include_dirs.append(py.path.local(pypydir).join('translator', 'c')) - library_dirs = list(eci.library_dirs) - if sys.platform == 'darwin': # support Fink & Darwinports - for s in ('/sw/', '/opt/local/'): - if s + 'include' not in include_dirs and \ - os.path.exists(s + 'include'): - include_dirs.append(s + 'include') - if s + 'lib' not in library_dirs and \ - os.path.exists(s + 'lib'): - library_dirs.append(s + 'lib') - - export_symbols = list(eci.export_symbols) - - num = 0 - modname = modbasename - while 1: - if not tmpdir.join(modname + so_ext).check(): - break - num += 1 - modname = '%s_%d' % (modbasename, num) - - lastdir = tmpdir.chdir() - libraries = eci.libraries - ensure_correct_math() - try: - if debug: print "modname", modname - c = stdoutcapture.Capture(mixed_out_err = True) - try: - try: - if compiler_command(): - # GCC-ish options only - from distutils import sysconfig - gcv = sysconfig.get_config_vars() - cmd = compiler_command().replace('%s', - str(tmpdir.join(modname))) - for dir in [gcv['INCLUDEPY']] + list(include_dirs): - cmd += ' -I%s' % dir - for dir in library_dirs: - cmd += ' -L%s' % dir - os.system(cmd) - else: - from distutils.dist import Distribution - from distutils.extension import Extension - from distutils.ccompiler import get_default_compiler - from distutils.command.build_ext import build_ext - - class build_shared_library(build_ext): - """ We build shared libraries, not python modules. - On windows, avoid to export the initXXX function, - and don't use a .pyd extension. """ - def get_export_symbols(self, ext): - return ext.export_symbols - def get_ext_filename (self, ext_name): - if sys.platform == 'win32': - return ext_name + ".dll" - else: - return ext_name + ".so" - - saved_environ = os.environ.items() - try: - # distutils.core.setup() is really meant for end-user - # interactive usage, because it eats most exceptions and - # turn them into SystemExits. Instead, we directly - # instantiate a Distribution, which also allows us to - # ignore unwanted features like config files. - extra_compile_args = [] - # ensure correct math on windows - if sys.platform == 'win32': - extra_compile_args.append('/Op') # get extra precision - if get_default_compiler() == 'unix': - old_version = False - try: - g = os.popen('gcc --version', 'r') - verinfo = g.read() - g.close() - except (OSError, IOError): - pass - else: - old_version = verinfo.startswith('2') - if not old_version: - extra_compile_args.extend(["-Wno-unused-label", - "-Wno-unused-variable"]) - attrs = { - 'name': "testmodule", - 'ext_modules': [ - Extension(modname, [str(cfile) for cfile in cfiles], - include_dirs=include_dirs, - library_dirs=library_dirs, - extra_compile_args=extra_compile_args, - libraries=list(libraries), - export_symbols=export_symbols, - ) - ], - 'script_name': 'setup.py', - 'script_args': ['-q', 'build_ext'], # don't remove 'build_ext' here - } - dist = Distribution(attrs) - # patch our own command obj into distutils - # because it does not have a facility to accept - # custom objects - cmdobj = build_shared_library(dist) - cmdobj.inplace = True - cmdobj.force = True - if (sys.platform == 'win32' - and sys.executable.lower().endswith('_d.exe')): - cmdobj.debug = True - dist.command_obj["build_ext"] = cmdobj - dist.have_run["build_ext"] = 0 - - if not dist.parse_command_line(): - raise ValueError, "distutils cmdline parse error" - dist.run_commands() - finally: - for key, value in saved_environ: - if os.environ.get(key) != value: - os.environ[key] = value - finally: - foutput, foutput = c.done() - data = foutput.read() - if data: - fdump = open("%s.errors" % modname, "w") - fdump.write(data) - fdump.close() - # XXX do we need to do some check on fout/ferr? - # XXX not a nice way to import a module - except: - print >>sys.stderr, data - raise - finally: - lastdir.chdir() - return str(tmpdir.join(modname) + so_ext) - -def make_module_from_c(cfile, eci): - cfile = py.path.local(cfile) - modname = cfile.purebasename - compile_c_module([cfile], modname, eci) - return import_module_from_directory(cfile.dirpath(), modname) - -def import_module_from_directory(dir, modname): - file, pathname, description = imp.find_module(modname, [str(dir)]) - try: - mod = imp.load_module(modname, file, pathname, description) - finally: - if file: - file.close() - return mod - - -def log_spawned_cmd(spawn): - def spawn_and_log(cmd, *args, **kwds): - log.execute(' '.join(cmd)) - return spawn(cmd, *args, **kwds) - return spawn_and_log - - -class ProfOpt(object): - #XXX assuming gcc style flags for now - name = "profopt" - - def __init__(self, compiler): - self.compiler = compiler - - def first(self): - self.build('-fprofile-generate') - - def probe(self, exe, args): - # 'args' is a single string typically containing spaces - # and quotes, which represents several arguments. - os.system("'%s' %s" % (exe, args)) - - def after(self): - self.build('-fprofile-use') - - def build(self, option): - compiler = self.compiler - compiler.fix_gcc_random_seed = True - compiler.compile_extra.append(option) - compiler.link_extra.append(option) - try: - compiler._build() - finally: - compiler.compile_extra.pop() - compiler.link_extra.pop() - -class CompilationError(Exception): - pass - -class CCompiler: - fix_gcc_random_seed = False - - def __init__(self, cfilenames, eci, outputfilename=None, - compiler_exe=None, profbased=None): - self.cfilenames = cfilenames - ext = '' - self.libraries = list(eci.libraries) - self.include_dirs = list(eci.include_dirs) - self.library_dirs = list(eci.library_dirs) - self.compile_extra = list(eci.compile_extra) - self.link_extra = list(eci.link_extra) - self.frameworks = list(eci.frameworks) - if compiler_exe is not None: - self.compiler_exe = compiler_exe - else: - self.compiler_exe = eci.platform.get_compiler() - self.profbased = profbased - if not sys.platform in ('win32', 'darwin'): # xxx - if 'm' not in self.libraries: - self.libraries.append('m') - self.compile_extra += CFLAGS + ['-fomit-frame-pointer'] - if 'pthread' not in self.libraries: - self.libraries.append('pthread') - if sys.platform != 'sunos5': - self.compile_extra += ['-pthread'] - self.link_extra += ['-pthread'] - else: - self.compile_extra += ['-pthreads'] - self.link_extra += ['-lpthread'] - if sys.platform == 'win32': - self.link_extra += ['/DEBUG'] # generate .pdb file - if sys.platform == 'darwin': - # support Fink & Darwinports - for s in ('/sw/', '/opt/local/'): - if s + 'include' not in self.include_dirs and \ - os.path.exists(s + 'include'): - self.include_dirs.append(s + 'include') - if s + 'lib' not in self.library_dirs and \ - os.path.exists(s + 'lib'): - self.library_dirs.append(s + 'lib') - self.compile_extra += CFLAGS + ['-fomit-frame-pointer'] - for framework in self.frameworks: - self.link_extra += ['-framework', framework] - - if outputfilename is None: - self.outputfilename = py.path.local(cfilenames[0]).new(ext=ext) - else: - self.outputfilename = py.path.local(outputfilename) - self.eci = eci - - def build(self, noerr=False): - import distutils.errors - basename = self.outputfilename.new(ext='') - data = '' - try: - saved_environ = os.environ.copy() - try: - c = stdoutcapture.Capture(mixed_out_err = True) - if self.profbased is None: - self._build() - else: - ProfDriver, args = self.profbased - profdrv = ProfDriver(self) - dolog = getattr(log, profdrv.name) - dolog(args) - profdrv.first() - dolog('Gathering profile data from: %s %s' % ( - str(self.outputfilename), args)) - profdrv.probe(str(self.outputfilename),args) - profdrv.after() - finally: - # workaround for a distutils bugs where some env vars can - # become longer and longer every time it is used - for key, value in saved_environ.items(): - if os.environ.get(key) != value: - os.environ[key] = value - foutput, foutput = c.done() - data = foutput.read() - if data: - fdump = basename.new(ext='errors').open("w") - fdump.write(data) - fdump.close() - except (distutils.errors.CompileError, - distutils.errors.LinkError), e: - data = data.rstrip() - if data: - data += '\n' - data += str(e) - raise CompilationError(data) - except: - if not noerr: - print >>sys.stderr, data - raise - - def _build(self): - from distutils.ccompiler import new_compiler - compiler = new_compiler(force=1) - if self.compiler_exe is not None: - for c in '''compiler compiler_so compiler_cxx - linker_exe linker_so'''.split(): - compiler.executables[c][0] = self.compiler_exe - compiler.spawn = log_spawned_cmd(compiler.spawn) - objects = [] - for cfile in self.cfilenames: - cfile = py.path.local(cfile) - compile_extra = self.compile_extra[:] - # -frandom-seed is only to try to be as reproducable as possible - if self.fix_gcc_random_seed: - compile_extra.append('-frandom-seed=%s' % (cfile.basename,)) - # XXX horrible workaround for a bug of profiling in gcc on - # OS X with functions containing a direct call to fork() - if '/*--no-profiling-for-this-file!--*/' in cfile.read(): - compile_extra = [arg for arg in compile_extra - if not arg.startswith('-fprofile-')] - - old = cfile.dirpath().chdir() - try: - res = compiler.compile([cfile.basename], - include_dirs=self.eci.include_dirs, - extra_preargs=compile_extra) - assert len(res) == 1 - cobjfile = py.path.local(res[0]) - assert cobjfile.check() - objects.append(str(cobjfile)) - finally: - old.chdir() - - compiler.link_executable(objects, str(self.outputfilename), - libraries=self.eci.libraries, - extra_preargs=self.link_extra, - library_dirs=self.eci.library_dirs) - -def build_executable(*args, **kwds): - noerr = kwds.pop('noerr', False) - compiler = CCompiler(*args, **kwds) - compiler.build(noerr=noerr) - return str(compiler.outputfilename) - -def check_boehm_presence(noerr=True): - from pypy.tool.udir import udir - try: - cfile = udir.join('check_boehm.c') - cfname = str(cfile) - cfile = cfile.open('w') - cfile.write(""" -#include - -int main() { - return 0; -} -""") - cfile.close() - if sys.platform == 'win32': - eci = ExternalCompilationInfo(libraries=['gc_pypy']) - else: - eci = ExternalCompilationInfo(libraries=['gc']) - build_executable([cfname], eci, noerr=noerr) - except CompilationError: - if noerr: - return False - else: - raise - else: - return True - def check_under_under_thread(): + xxx from pypy.tool.udir import udir cfile = py.path.local(autopath.this_dir).join('__thread_test.c') fsource = cfile.open('r') Modified: pypy/trunk/pypy/translator/tool/test/test_cbuild.py ============================================================================== --- pypy/trunk/pypy/translator/tool/test/test_cbuild.py (original) +++ pypy/trunk/pypy/translator/tool/test/test_cbuild.py Thu Oct 23 12:32:04 2008 @@ -1,26 +1,8 @@ import py, sys from pypy.tool.udir import udir -from pypy.translator.tool.cbuild import build_executable, \ - ExternalCompilationInfo, compile_c_module +from pypy.translator.tool.cbuild import ExternalCompilationInfo from subprocess import Popen, PIPE, STDOUT -from pypy.rlib.pyplatform import Maemo - -def test_simple_executable(): - print udir - testpath = udir.join('testbuildexec') - t = testpath.ensure("test.c") - t.write(r""" - #include - int main() { - printf("hello world\n"); - return 0; - } -""") - eci = ExternalCompilationInfo() - testexec = build_executable([t], eci) - out = py.process.cmdexec(testexec) - assert out.startswith('hello world') class TestEci: def setup_class(cls): @@ -34,28 +16,6 @@ ''')) cls.modfile = c_file cls.tmpdir = tmpdir - - def test_standalone(self): - tmpdir = self.tmpdir - c_file = tmpdir.join('stand1.c') - c_file.write(''' - #include - #include - - int main() - { - printf("%f\\n", pow(2.0, 2.0)); - }''') - if sys.platform != 'win32': - eci = ExternalCompilationInfo( - libraries = ['m'], - ) - else: - eci = ExternalCompilationInfo() - output = build_executable([c_file], eci) - p = Popen(output, stdout=PIPE, stderr=STDOUT) - p.wait() - assert p.stdout.readline().startswith('4.0') def test_merge(self): e1 = ExternalCompilationInfo( @@ -158,69 +118,13 @@ ExternalCompilationInfo.from_config_tool, 'dxowqbncpqympqhe-config') - def test_platform(self): - from pypy.rlib.pyplatform import Platform - class Expected(Exception): - pass - - class X(Platform): - def get_compiler(self): - raise Expected - - def execute(self): - return 3 + def test_platforms(self): + from pypy.translator.platform import Platform - eci = ExternalCompilationInfo(platform=X()) - try: - build_executable([self.modfile], eci) - except Expected: - pass - else: - py.test.fail("Did not raise") - assert eci.platform.execute() == 3 - - def test_platform_equality(self): - from pypy.rlib.pyplatform import Platform - class X(Platform): - pass - class Y(Platform): - def __init__(self, x): - self.x = x - - assert X() == X() - assert Y(3) == Y(3) - assert Y(2) != Y(3) - - def checkscratchbox(self): - if not py.path.local('/scratchbox/login').check(): - py.test.skip("No scratchbox detected") - - def test_standalone_maemo(self): - self.checkscratchbox() - # XXX skip if there is no scratchbox - tmpdir = self.tmpdir - c_file = tmpdir.join('stand1.c') - c_file.write(''' - #include - #include + class Maemo(Platform): + def __init__(self, cc=None): + self.cc = cc - int main() - { - printf("%f\\n", pow(2.0, 2.0)); - return 0; - }''') - if sys.platform == 'win32': - py.test.skip("No cross-compilation on windows yet") - else: - eci = ExternalCompilationInfo(platform=Maemo(), - libraries=['m']) - output = build_executable([c_file], eci) - py.test.raises(py.process.cmdexec.Error, py.process.cmdexec, output) - result = eci.platform.execute(output) - assert result.startswith('4.0') - - def test_platforms(self): - self.checkscratchbox() eci = ExternalCompilationInfo(platform=Maemo()) eci2 = ExternalCompilationInfo() assert eci != eci2 Modified: pypy/trunk/pypy/translator/translator.py ============================================================================== --- pypy/trunk/pypy/translator/translator.py (original) +++ pypy/trunk/pypy/translator/translator.py Thu Oct 23 12:32:04 2008 @@ -13,6 +13,7 @@ from pypy.tool.sourcetools import nice_repr_for_func from pypy.config.pypyoption import pypy_optiondescription from pypy.config.translationoption import get_combined_translation_config +from pypy.config.translationoption import get_platform import py log = py.log.Producer("flowgraph") py.log.setconsumer("flowgraph", ansi_log) @@ -36,6 +37,7 @@ if attr in flowing_flags: setattr(config.translation, attr, flowing_flags[attr]) self.config = config + self.platform = get_platform(config) self.create_flowspace_config() self.annotator = None self.rtyper = None From fijal at codespeak.net Thu Oct 23 12:34:00 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 23 Oct 2008 12:34:00 +0200 (CEST) Subject: [pypy-svn] r59330 - pypy/branch/cbuild-refactor Message-ID: <20081023103400.D0A1A16A0EE@codespeak.net> Author: fijal Date: Thu Oct 23 12:34:00 2008 New Revision: 59330 Removed: pypy/branch/cbuild-refactor/ Log: remove merged branch From fijal at codespeak.net Thu Oct 23 12:35:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 23 Oct 2008 12:35:33 +0200 (CEST) Subject: [pypy-svn] r59331 - pypy/trunk/pypy/rpython/memory/gc Message-ID: <20081023103533.C913F16A0D6@codespeak.net> Author: fijal Date: Thu Oct 23 12:35:33 2008 New Revision: 59331 Modified: pypy/trunk/pypy/rpython/memory/gc/markcompact.py Log: Introduce an optimization that keeps tid and flags in the same place as forwarding pointer. Right now it's very rough and includes some code repetition, I'll clean it afterwards. It also stores full word per typeid for simplicity. This can be improved. Modified: pypy/trunk/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/markcompact.py Thu Oct 23 12:35:33 2008 @@ -12,10 +12,9 @@ from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.objectmodel import we_are_translated -TYPEID_MASK = 0xffff -first_gcflag = 1 << 16 +TYPEID_MASK = 0xffff0000 +first_gcflag = 2 GCFLAG_MARKBIT = first_gcflag << 0 -GCFLAG_EXTERNAL = first_gcflag << 1 memoryError = MemoryError() @@ -51,6 +50,11 @@ # we bump next_collect_after which is a marker where to start each collection. # It should be exponential (but less than 2) from the size occupied by objects +# field optimization - we don't need forward pointer and flags at the same +# time. Instead we copy list of tids when we know how many objects are alive +# and store forward pointer there. + + # in case we need to grow space, we use # current_space_size * FREE_SPACE_MULTIPLIER / FREE_SPACE_DIVIDER + needed FREE_SPACE_MULTIPLIER = 3 @@ -60,8 +64,10 @@ GC_CLEARANCE = 32*1024 class MarkCompactGC(MovingGCBase): - HDR = lltype.Struct('header', ('tid', lltype.Signed), - ('forward_ptr', llmemory.Address)) + HDR = lltype.Struct('header', ('forward_ptr', llmemory.Address)) + TID_BACKUP = lltype.Array(lltype.Signed) + WEAKREF_OFFSETS = lltype.Array(lltype.Signed) + TRANSLATION_PARAMS = {'space_size': 8*1024*1024} # XXX adjust @@ -87,29 +93,28 @@ MovingGCBase.setup(self) self.objects_with_finalizers = self.AddressDeque() self.objects_with_weakrefs = self.AddressStack() + self.tid_backup_stack = self.AddressStack() + self.tid_backup = lltype.nullptr(self.TID_BACKUP) - def init_gc_object(self, addr, typeid, flags=0): + # flags = 1 to make lltype & llmemory happy about odd/even pointers + + def init_gc_object(self, addr, typeid, flags=1): hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) - hdr.tid = typeid | flags - hdr.forward_ptr = NULL + hdr.forward_ptr = llmemory.cast_int_to_adr((typeid << 16) | flags) - def init_gc_object_immortal(self, addr, typeid, flags=0): + def init_gc_object_immortal(self, addr, typeid, flags=1): hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) - hdr.tid = typeid | flags | GCFLAG_EXTERNAL - hdr.forward_ptr = NULL + hdr.forward_ptr = llmemory.cast_int_to_adr((typeid << 16) | flags) # XXX we can store forward_ptr to itself, if we fix C backend # so that get_forwarding_address(obj) returns # obj itself if obj is a prebuilt object def malloc_fixedsize_clear(self, typeid, size, can_collect, has_finalizer=False, contains_weakptr=False): - ll_assert(can_collect, "can collect is False") size_gc_header = self.gcheaderbuilder.size_gc_header totalsize = size_gc_header + size result = self.free if raw_malloc_usage(totalsize) > self.top_of_space - result: - if not can_collect: - raise memoryError result = self.obtain_free_space(totalsize) llarena.arena_reserve(result, totalsize) self.init_gc_object(result, typeid) @@ -123,7 +128,6 @@ def malloc_varsize_clear(self, typeid, length, size, itemsize, offset_to_length, can_collect, has_finalizer=False): - ll_assert(can_collect, "can collect is False") size_gc_header = self.gcheaderbuilder.size_gc_header nonvarsize = size_gc_header + size try: @@ -133,8 +137,6 @@ raise memoryError result = self.free if raw_malloc_usage(totalsize) > self.top_of_space - result: - if not can_collect: - raise memoryError result = self.obtain_free_space(totalsize) llarena.arena_reserve(result, totalsize) self.init_gc_object(result, typeid) @@ -170,9 +172,10 @@ toaddr = llarena.arena_malloc(self.space_size, True) return toaddr - def compute_size_of_alive_objects(self): + def compute_alive_objects(self): fromaddr = self.space totalsize = 0 + num = 1 while fromaddr < self.free: size_gc_header = self.gcheaderbuilder.size_gc_header hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) @@ -181,11 +184,14 @@ objtotalsize = size_gc_header + objsize if self.marked(obj): totalsize += raw_malloc_usage(objtotalsize) + num += 1 fromaddr += objtotalsize - return totalsize + self.totalsize_of_objs = totalsize + return num def collect(self): self.markcompactcollect() + def markcompactcollect(self, needed=0): start_time = self.debug_collect_start() self.debug_check_consistency() @@ -196,8 +202,9 @@ self.mark_objects_with_finalizers() self._trace_and_mark() self.to_see.delete() - totalsize = self.new_space_size(self.compute_size_of_alive_objects(), - needed) + num_of_alive_objs = self.compute_alive_objects() + size_of_alive_objs = self.totalsize_of_objs + totalsize = self.new_space_size(size_of_alive_objs, needed) if totalsize >= self.space_size: toaddr = self.double_space_size(totalsize) resizing = True @@ -205,12 +212,13 @@ toaddr = llarena.arena_new_view(self.space) resizing = False self.next_collect_after = totalsize - finaladdr = self.update_forward_pointers(toaddr) + weakref_offsets = self.collect_weakref_offsets() + finaladdr = self.update_forward_pointers(toaddr, num_of_alive_objs) if (self.run_finalizers.non_empty() or self.objects_with_finalizers.non_empty()): self.update_run_finalizers() if self.objects_with_weakrefs.non_empty(): - self.invalidate_weakrefs() + self.invalidate_weakrefs(weakref_offsets) self.update_objects_with_id() self.compact(resizing) if not resizing: @@ -228,6 +236,26 @@ if self.run_finalizers.non_empty(): self.execute_finalizers() self.debug_collect_finish(start_time) + lltype.free(self.tid_backup, flavor='raw') + if self.tid_backup_stack.non_empty(): + self.tid_backup = llmemory.cast_adr_to_ptr(self.tid_backup_stack.pop(), lltype.Ptr(self.TID_BACKUP)) + else: + self.tid_backup = lltype.nullptr(self.TID_BACKUP) + + def collect_weakref_offsets(self): + weakrefs = self.objects_with_weakrefs + new_weakrefs = self.AddressStack() + weakref_offsets = lltype.malloc(self.WEAKREF_OFFSETS, + weakrefs.length(), flavor='raw') + i = 0 + while weakrefs.non_empty(): + obj = weakrefs.pop() + offset = self.weakpointer_offset(self.get_type_id(obj)) + weakref_offsets[i] = offset + new_weakrefs.append(obj) + i += 1 + self.objects_with_weakrefs = new_weakrefs + return weakref_offsets def debug_collect_start(self): if self.config.gcconfig.debugprint: @@ -276,8 +304,11 @@ self.objects_with_finalizers.delete() self.objects_with_finalizers = objects_with_finalizers + def get_tid(self, addr): + return llmemory.cast_adr_to_int(self.header(addr).forward_ptr) + def get_type_id(self, addr): - return self.header(addr).tid & TYPEID_MASK + return self.get_tid(addr) >> 16 def mark_roots_recursively(self): self.root_walker.walk_roots( @@ -304,25 +335,35 @@ self.to_see.append(root.address[0]) def mark(self, obj): - self.header(obj).tid |= GCFLAG_MARKBIT + previous = self.get_tid(obj) + self.header(obj).forward_ptr = llmemory.cast_int_to_adr(previous | GCFLAG_MARKBIT) def marked(self, obj): - return self.header(obj).tid & GCFLAG_MARKBIT + return self.get_tid(obj) & GCFLAG_MARKBIT - def update_forward_pointers(self, toaddr): + def update_forward_pointers(self, toaddr, num_of_alive_objs): fromaddr = self.space size_gc_header = self.gcheaderbuilder.size_gc_header + # XXX one can adjust this not to keep word per object, but instead + # just number of used bits + if self.tid_backup: + self.tid_backup_stack.append(llmemory.cast_ptr_to_adr(self.tid_backup)) + self.tid_backup = lltype.malloc(self.TID_BACKUP, num_of_alive_objs, + flavor='raw') + i = 0 while fromaddr < self.free: hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) obj = fromaddr + size_gc_header objsize = self.get_size(obj) totalsize = size_gc_header + objsize if not self.marked(obj): - pass + self.set_forwarding_address(obj, NULL, i) + hdr.forward_ptr = NULL else: llarena.arena_reserve(toaddr, totalsize) - self.set_forwarding_address(obj, toaddr) + self.set_forwarding_address(obj, toaddr, i) toaddr += totalsize + i += 1 fromaddr += totalsize # now update references @@ -331,18 +372,55 @@ MarkCompactGC._update_root, # static in prebuilt non-gc structures MarkCompactGC._update_root) # static in prebuilt gc objects fromaddr = self.space + i = 0 while fromaddr < self.free: hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) obj = fromaddr + size_gc_header - objsize = self.get_size(obj) + objsize = self.get_size_from_backup(obj, i) totalsize = size_gc_header + objsize - if not self.marked(obj): + if not self.surviving(obj): pass else: - self.trace(obj, self._update_ref, None) + self.trace_with_backup(obj, self._update_ref, i) fromaddr += totalsize + i += 1 return toaddr + def trace_with_backup(self, obj, callback, arg): + """Enumerate the locations inside the given obj that can contain + GC pointers. For each such location, callback(pointer, arg) is + called, where 'pointer' is an address inside the object. + Typically, 'callback' is a bound method and 'arg' can be None. + """ + typeid = self.get_typeid_from_backup(arg) + if self.is_gcarrayofgcptr(typeid): + # a performance shortcut for GcArray(gcptr) + length = (obj + llmemory.gcarrayofptr_lengthoffset).signed[0] + item = obj + llmemory.gcarrayofptr_itemsoffset + while length > 0: + callback(item, arg) + item += llmemory.gcarrayofptr_singleitemoffset + length -= 1 + return + offsets = self.offsets_to_gc_pointers(typeid) + i = 0 + while i < len(offsets): + callback(obj + offsets[i], arg) + i += 1 + if self.has_gcptr_in_varsize(typeid): + item = obj + self.varsize_offset_to_variable_part(typeid) + length = (obj + self.varsize_offset_to_length(typeid)).signed[0] + offsets = self.varsize_offsets_to_gcpointers_in_var_part(typeid) + itemlength = self.varsize_item_sizes(typeid) + while length > 0: + j = 0 + while j < len(offsets): + callback(item + offsets[j], arg) + j += 1 + item += itemlength + length -= 1 + trace_with_backup._annspecialcase_ = 'specialize:arg(2)' + def _update_root(self, pointer): if pointer.address[0] != NULL: pointer.address[0] = self.get_forwarding_address(pointer.address[0]) @@ -355,29 +433,49 @@ return self.header(addr).forward_ptr != NULL def _is_external(self, obj): - # XXX might change - return self.header(obj).tid & GCFLAG_EXTERNAL + return not (obj >= self.space and obj < self.free) def get_forwarding_address(self, obj): if self._is_external(obj): return obj return self.header(obj).forward_ptr + self.size_gc_header() - def set_forwarding_address(self, obj, newaddr): + def set_forwarding_address(self, obj, newaddr, num): + self.backup_typeid(num, obj) self.header(obj).forward_ptr = newaddr def surviving(self, obj): return self.header(obj).forward_ptr != NULL + def backup_typeid(self, num, obj): + self.tid_backup[num] = self.get_type_id(obj) + + def get_typeid_from_backup(self, num): + return self.tid_backup[num] + + def get_size_from_backup(self, obj, num): + typeid = self.get_typeid_from_backup(num) + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + lenaddr = obj + self.varsize_offset_to_length(typeid) + length = lenaddr.signed[0] + size += length * self.varsize_item_sizes(typeid) + size = llarena.round_up_for_allocation(size) + # XXX maybe we should parametrize round_up_for_allocation() + # per GC; if we do, we also need to fix the call in + # gctypelayout.encode_type_shape() + return size + def compact(self, resizing): fromaddr = self.space size_gc_header = self.gcheaderbuilder.size_gc_header start = fromaddr end = fromaddr + num = 0 while fromaddr < self.free: - hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) obj = fromaddr + size_gc_header - objsize = self.get_size(obj) + hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) + objsize = self.get_size_from_backup(obj, num) totalsize = size_gc_header + objsize if not self.surviving(obj): # this object dies. Following line is a noop in C, @@ -388,8 +486,8 @@ forward_ptr = hdr.forward_ptr if resizing: end = fromaddr - hdr.forward_ptr = NULL - hdr.tid &= ~GCFLAG_MARKBIT + val = (self.get_typeid_from_backup(num) << 16) + 1 + hdr.forward_ptr = llmemory.cast_int_to_adr(val) if fromaddr != forward_ptr: #llop.debug_print(lltype.Void, "Copying from to", # fromaddr, forward_ptr, totalsize) @@ -405,14 +503,12 @@ # here in case of test_gc llarena.arena_reset(start, diff, True) start += diff - + num += 1 fromaddr += totalsize def debug_check_object(self, obj): # not sure what to check here - if not self._is_external(obj): - ll_assert(not self.marked(obj), "Marked") - ll_assert(not self.surviving(obj), "forward_ptr set") + pass def mark_objects_with_finalizers(self): new_with_finalizers = self.AddressDeque() @@ -436,17 +532,18 @@ self.objects_with_finalizers.delete() self.objects_with_finalizers = new_with_finalizers - def invalidate_weakrefs(self): + def invalidate_weakrefs(self, weakref_offsets): # walk over list of objects that contain weakrefs # if the object it references survives then update the weakref # otherwise invalidate the weakref new_with_weakref = self.AddressStack() + i = 0 while self.objects_with_weakrefs.non_empty(): obj = self.objects_with_weakrefs.pop() if not self.surviving(obj): continue # weakref itself dies newobj = self.get_forwarding_address(obj) - offset = self.weakpointer_offset(self.get_type_id(obj)) + offset = weakref_offsets[i] pointing_to = (obj + offset).address[0] # XXX I think that pointing_to cannot be NULL here if pointing_to: @@ -456,5 +553,7 @@ new_with_weakref.append(newobj) else: (obj + offset).address[0] = NULL + i += 1 self.objects_with_weakrefs.delete() self.objects_with_weakrefs = new_with_weakref + lltype.free(weakref_offsets, flavor='raw') From arigo at codespeak.net Thu Oct 23 16:29:08 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 23 Oct 2008 16:29:08 +0200 (CEST) Subject: [pypy-svn] r59338 - pypy/trunk/lib-python Message-ID: <20081023142908.75DC516A236@codespeak.net> Author: arigo Date: Thu Oct 23 16:29:06 2008 New Revision: 59338 Modified: pypy/trunk/lib-python/failure_list.txt Log: Started a quick review of the lib-python failures reported by buildbot. Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Thu Oct 23 16:29:06 2008 @@ -1,129 +1,117 @@ -arigo at wyvern ~/svn/pypy/branch/2.5-merge/lib-python/modified-2.5.2/test $ py.test --pypy=/home/arigo/pypysrc/compiled/pypy-c-58675-2.5-O1 -k core --tb=no -inserting into sys.path: /home/arigo/svn/pypy/branch/2.5-merge -================================================================ test session starts ================================================================ -HOSTUP: localhost-0 linux2 /usr/bin/python - Python 2.4.4-final-0 - -test___all__.py . -../../2.5.2/test/test___future__.py . -test_array.py . -../../2.5.2/test/test_atexit.py . -../../2.5.2/test/test_augassign.py . -../../2.5.2/test/test_binop.py . -../../2.5.2/test/test_bisect.py . -../../2.5.2/test/test_bool.py . -test_bufio.py . -test_builtin.py . -../../2.5.2/test/test_call.py . -../../2.5.2/test/test_charmapcodec.py . -test_class.py . -../../2.5.2/test/test_cmath.py . -../../2.5.2/test/test_codeccallbacks.py F -test_codecs.py F -test_codeop.py . -../../2.5.2/test/test_coercion.py F -../../2.5.2/test/test_compare.py . -test_compile.py F -test_complex.py . -../../2.5.2/test/test_contains.py . -test_copy.py . -../../2.5.2/test/test_copy_reg.py . -test_cpickle.py F -../../2.5.2/test/test_decorators.py . -test_deque.py F -test_descr.py F -test_descrtut.py . -test_dict.py F -../../2.5.2/test/test_dircache.py . -../../2.5.2/test/test_dummy_thread.py . -../../2.5.2/test/test_dummy_threading.py . -test_enumerate.py . -../../2.5.2/test/test_eof.py F -test_exceptions.py F -../../2.5.2/test/test_extcall.py F -test_file.py F -../../2.5.2/test/test_filecmp.py . -../../2.5.2/test/test_fileinput.py . -../../2.5.2/test/test_fnmatch.py . -test_format.py F -../../2.5.2/test/test_fpformat.py . -test_funcattrs.py F -../../2.5.2/test/test_future.py . -../../2.5.2/test/test_future1.py . -../../2.5.2/test/test_future2.py . -../../2.5.2/test/test_future3.py . -test_generators.py F -test_genexps.py F -../../2.5.2/test/test_getopt.py f -../../2.5.2/test/test_glob.py . -../../2.5.2/test/test_global.py . -../../2.5.2/test/test_grammar.py F -../../2.5.2/test/test_hash.py . -../../2.5.2/test/test_hashlib.py f -../../2.5.2/test/test_heapq.py . -../../2.5.2/test/test_hexoct.py . -../../2.5.2/test/test_imp.py . -../../2.5.2/test/test_import.py f -../../2.5.2/test/test_importhooks.py F -../../2.5.2/test/test_isinstance.py F -test_iter.py . -../../2.5.2/test/test_iterlen.py F -test_itertools.py F -../../2.5.2/test/test_list.py F -../../2.5.2/test/test_long.py F -../../2.5.2/test/test_long_future.py . -../../2.5.2/test/test_longexp.py . -test_marshal.py F -../../2.5.2/test/test_math.py . -test_module.py . -../../2.5.2/test/test_multibytecodec_support.py . -test_mutants.py . -../../2.5.2/test/test_new.py F -../../2.5.2/test/test_opcodes.py . -test_operations.py . -../../2.5.2/test/test_operator.py F -test_os.py . -test_parser.py F -../../2.5.2/test/test_pickle.py F -../../2.5.2/test/test_pkg.py . -../../2.5.2/test/test_pkgimport.py . -../../2.5.2/test/test_pow.py . -../../2.5.2/test/test_pprint.py . -../../2.5.2/test/test_profilehooks.py . -test_re.py F -test_repr.py F -../../2.5.2/test/test_richcmp.py . -test_scope.py . -test_set.py F -test_slice.py . -../../2.5.2/test/test_softspace.py . -test_sort.py F -../../2.5.2/test/test_str.py F -../../2.5.2/test/test_string.py F -../../2.5.2/test/test_StringIO.py . -../../2.5.2/test/test_syntax.py F -test_sys.py F -../../2.5.2/test/test_thread.py F -../../2.5.2/test/test_threaded_import.py F -../../2.5.2/test/test_threading.py F -../../2.5.2/test/test_threading_local.py F -../../2.5.2/test/test_time.py F -test_trace.py F -test_traceback.py F -../../2.5.2/test/test_transformer.py . -../../2.5.2/test/test_tuple.py F -../../2.5.2/test/test_types.py . -../../2.5.2/test/test_unary.py . -../../2.5.2/test/test_unicode.py F -../../2.5.2/test/test_unittest.py . -../../2.5.2/test/test_univnewlines.py f -test_unpack.py F -../../2.5.2/test/test_userdict.py . -../../2.5.2/test/test_userlist.py F -test_userstring.py F -../../2.5.2/test/test_warnings.py . -test_weakref.py F -test_xrange.py . - -========================================================== 174 tests deselected by 'core' =========================================================== -===================================================== 65/120 passed + 0 skips in 459.34 seconds ===================================================== -=================================================================== failures: 55 ==================================================================== +test name !=must fix guess at failure cause or difficulty +------------------------------------------------------------------------------------------- +test__locale +test_ast +test_bigmem +test_binascii +test_builtin +test_cProfile +test_capi +test_cmd_line +test_code +test_codeccallbacks +test_codecs +test_coding +test_coercion +test_commands +test_compile +test_compiler +test_contextlib +test_ctypes +test_datetime +test_decimal +test_descr +test_descrtut +test_dis +test_distutils +test_doctest +test_dumbdbm +test_email +test_email_codecs +test_email_renamed +test_enumerate +test_exception_variations +test_exceptions +test_file +test_float +test_fork1 +test_format +test_funcattrs +test_functools +test_gc +test_generators +test_genexps +test_gettext +test_grammar +test_hmac +test_import +test_importhooks +test_inspect +test_ioctl +test_isinstance +test_iterlen +test_itertools +test_logging +test_long +test_mailbox +test_multibytecodec +test_mutants +test_new +test_normalization +test_optparse +test_parser +test_peepholer +test_pep277 +test_platform +test_plistlib +test_poll +test_profile +test_pyclbr +test_pyexpat +test_quopri +test_random +test_re +test_repr +test_sax +test_sets +test_shelve +test_signal +test_site +test_socket +test_socketserver +test_sort +test_sqlite +test_startfile what is os.startfile? +test_str ! segfault :-( +test_string ! segfault :-( +test_struct ! struct.pack() range checking sometimes less strict in CPython +test_structmembers CPython-only +test_subprocess ! missing resource.error. no clue about os.fpathconf(). +test_syntax more small hacking here and there in the ast compiler +test_sys missing sys._current_frames() +test_tarfile ! timeout? +test_thread the docs say it's ok to raise thread.error here, but maybe we need to have thread.stack_size() implemented anyway (no hurry I'd say) +test_threading the failure should be marked as CPython-only +test_time ! easy fix (either bogus test or bogus time.strftime()) +test_timeout skipped test +test_trace probably all acceptable differences +test_traceback ! don't care about '__members__', but check the other tests +test_tuple ! might be fixed now, check again +test_unicode ! segfault :-( +test_unicode_file skipped test +test_unicodedata unknown to me (but xorAxAx and fijal have a better clue) +test_urllib2_localnet bogus test? +test_urllib2net skipped test +test_urllibnet skipped test +test_userstring ! unknown +test_uu ! unknown +test_wait3 no os.wait3() +test_wait4 no os.wait4() +test_weakref probably missing some gc.collect() +test_with minor hacking in the ast compiler +test_xml_etree_c import _elementtree +test_xmlrpc sys.setdefaultencoding missing +test_zipfile ! see test_struct +test_zipfile64 skipped test +test_zipimport many failures. the test itself seems not to run correctly +test_zlib ! easy to fix From arigo at codespeak.net Thu Oct 23 18:15:35 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 23 Oct 2008 18:15:35 +0200 (CEST) Subject: [pypy-svn] r59341 - pypy/trunk/lib-python Message-ID: <20081023161535.53BAE16A200@codespeak.net> Author: arigo Date: Thu Oct 23 18:15:34 2008 New Revision: 59341 Modified: pypy/trunk/lib-python/failure_list.txt Log: Finished the quick review. Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Thu Oct 23 18:15:34 2008 @@ -1,86 +1,86 @@ test name !=must fix guess at failure cause or difficulty ------------------------------------------------------------------------------------------- -test__locale -test_ast -test_bigmem -test_binascii -test_builtin -test_cProfile -test_capi -test_cmd_line -test_code -test_codeccallbacks -test_codecs -test_coding -test_coercion -test_commands -test_compile -test_compiler -test_contextlib -test_ctypes -test_datetime -test_decimal -test_descr -test_descrtut -test_dis -test_distutils -test_doctest -test_dumbdbm -test_email -test_email_codecs -test_email_renamed -test_enumerate -test_exception_variations -test_exceptions -test_file -test_float -test_fork1 -test_format -test_funcattrs -test_functools -test_gc -test_generators -test_genexps -test_gettext -test_grammar -test_hmac -test_import -test_importhooks -test_inspect -test_ioctl -test_isinstance -test_iterlen -test_itertools -test_logging -test_long -test_mailbox -test_multibytecodec -test_mutants -test_new -test_normalization -test_optparse -test_parser -test_peepholer -test_pep277 -test_platform -test_plistlib -test_poll -test_profile -test_pyclbr -test_pyexpat -test_quopri -test_random -test_re -test_repr -test_sax -test_sets -test_shelve -test_signal -test_site -test_socket -test_socketserver -test_sort -test_sqlite +test__locale ! unknown +test_ast import _ast +test_bigmem ! one looks like bug, the others like impl details +test_binascii ! looks like a bug +test_builtin this is our issue383 +test_cProfile ! unknown (do we still need to fix module/cProfile?) +test_capi CPython only +test_cmd_line ! implement "pypy-c -V" +test_code obscure differences in code objects produced by compiler +test_codeccallbacks ! unknown +test_codecs ! unknown +test_coding ! hah. fix buildbot :-/ +test_coercion ! look at test_prefix_binops, the other is probably too obscure +test_commands ! unknown +test_compile ! test_leading_newlines: impl detail; the rest: not good +test_compiler ! unknown +test_contextlib ! should be fixed, probably not too hard +test_ctypes ! implementation details but also some real crashes +test_datetime ! the two test_negative_*() look like real bugs +test_decimal missing decimal.ROUND_05UP +test_descr ! typo in modified/test_descr? +test_descrtut implementation detail only +test_dis probably not worth the pain of whacking at the compiler +test_distutils this is our issue367 +test_doctest ! unknown +test_dumbdbm ! oups? looks unexpected +test_email ! annoying failures, look at me +test_email_codecs test skipped +test_email_renamed ! same as test_email +test_enumerate same as test_iterlen +test_exception_variations ! uh? +test_exceptions ! typo in modified/test_exceptions +test_file some more exceptions should be raised +test_float float.__getformat__() exists mainly only for tests +test_fork1 ! why did this fail just once? +test_format test checking for exact exception messages +test_funcattrs ! easy to add this new attribute +test_functools ! missing gc.collect(); some impl details; del p.__dict__? +test_gc internal stuff, we may want to provide placeholders +test_generators ! I really hate our bytecode compiler :-( +test_genexps ! Fatal RPython error: InternalCompilerError :-( +test_gettext ! check this use of unicode() +test_grammar implementation detail +test_hmac ! looks bad! +test_import importing from pyc-files-without-py-file disabled by default +test_importhooks ! unknown +test_inspect ! test_wrapped_decorator: try to fix; isbuiltin([].append): cry and maaaybe try to fix +test_ioctl missing os.getpgrp() +test_isinstance ! mark the recursion limit tests as CPython-specific +test_iterlen somehow implementation detail (missing __length_hint__()) +test_itertools same as test_iterlen +test_logging ! shallow. let's just fix the __repr__ of types +test_long ! easy fixes +test_mailbox ! look at me +test_multibytecodec ! unknown +test_mutants the test is probably too precise in the failure it expects +test_new new.instancemethod(x, None) should fail, but no hurry +test_normalization test skipped +test_optparse ! test needs some fixes, but still, some failures are strange +test_parser missing parser.compilest(). I don't think we care for now +test_peepholer implementation detail (might be useful to look, though) +test_pep277 NT only +test_platform ! we should ensure that our sys.version is compatible enough do that the unmodified _sys_version_parser regexp recognizes it +test_plistlib plistlib seems to be Mac only +test_poll easy fix, I suppose +test_profile ! why is the "profile.py" module not found?? +test_pyclbr ! this import should find test/pyclbr_input.py +test_pyexpat is that an implementation detail? +test_quopri ! check if test_script{en,de}code() shows a real bug +test_random should probably be fixed, but no hurry i guess +test_re obscure, looks like yet another case not covered by test_sub_unicode in pypy/module/_sre/ +test_repr implementation detail +test_sax ! unknown +test_sets ! is this another CPython implementation detail test? +test_shelve ! unknown +test_signal ! missing signal.alarm(), probably easy to add +test_site ! fix me +test_socket ! uh? +test_socketserver test skipped +test_sort implementation detail +test_sqlite ! why no sqlite available? test_startfile what is os.startfile? test_str ! segfault :-( test_string ! segfault :-( From fijal at codespeak.net Thu Oct 23 19:31:19 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 23 Oct 2008 19:31:19 +0200 (CEST) Subject: [pypy-svn] r59342 - pypy/trunk/pypy/rpython/memory/gc Message-ID: <20081023173119.EDA8A16A26B@codespeak.net> Author: fijal Date: Thu Oct 23 19:31:18 2008 New Revision: 59342 Modified: pypy/trunk/pypy/rpython/memory/gc/markcompact.py Log: (fijal, arigo) A bit of simplification. Put tid_backup as the outermost call in this function Modified: pypy/trunk/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/markcompact.py Thu Oct 23 19:31:18 2008 @@ -93,7 +93,6 @@ MovingGCBase.setup(self) self.objects_with_finalizers = self.AddressDeque() self.objects_with_weakrefs = self.AddressStack() - self.tid_backup_stack = self.AddressStack() self.tid_backup = lltype.nullptr(self.TID_BACKUP) # flags = 1 to make lltype & llmemory happy about odd/even pointers @@ -233,15 +232,12 @@ self.free = finaladdr self.top_of_space = toaddr + self.next_collect_after self.debug_check_consistency() + lltype.free(self.tid_backup, flavor='raw') + self.tid_backup = lltype.nullptr(self.TID_BACKUP) if self.run_finalizers.non_empty(): self.execute_finalizers() self.debug_collect_finish(start_time) - lltype.free(self.tid_backup, flavor='raw') - if self.tid_backup_stack.non_empty(): - self.tid_backup = llmemory.cast_adr_to_ptr(self.tid_backup_stack.pop(), lltype.Ptr(self.TID_BACKUP)) - else: - self.tid_backup = lltype.nullptr(self.TID_BACKUP) - + def collect_weakref_offsets(self): weakrefs = self.objects_with_weakrefs new_weakrefs = self.AddressStack() @@ -255,6 +251,7 @@ new_weakrefs.append(obj) i += 1 self.objects_with_weakrefs = new_weakrefs + weakrefs.delete() return weakref_offsets def debug_collect_start(self): @@ -346,8 +343,6 @@ size_gc_header = self.gcheaderbuilder.size_gc_header # XXX one can adjust this not to keep word per object, but instead # just number of used bits - if self.tid_backup: - self.tid_backup_stack.append(llmemory.cast_ptr_to_adr(self.tid_backup)) self.tid_backup = lltype.malloc(self.TID_BACKUP, num_of_alive_objs, flavor='raw') i = 0 From xoraxax at codespeak.net Thu Oct 23 23:40:28 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 23 Oct 2008 23:40:28 +0200 (CEST) Subject: [pypy-svn] r59345 - pypy/trunk/pypy/doc Message-ID: <20081023214028.258B016A134@codespeak.net> Author: xoraxax Date: Thu Oct 23 23:40:26 2008 New Revision: 59345 Modified: pypy/trunk/pypy/doc/maemo.txt Log: Rewrite maemo.txt. Remove the debian target setup part, it was completely useless. The current idea is to refer to the well written installation instructions and point out important steps besides explaining all PyPy specific things. The remaining parts are useless now IMHO. Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Thu Oct 23 23:40:26 2008 @@ -4,33 +4,134 @@ XXX this document needs cleanup, contains duplicate information, will need cleanup after experiments yielded the best way to do pypy-c translations. -This is a short introduction how to install correct environment and -cross-compile pypy to maemo platform emulator under qemu. Note that this -is work-in-progress. +This is a short introduction that explains how to obtain a cross-compiled binary +of PyPy for the Maemo platform. +Cross compilation means that a certain environment will produce an +executable binary which can then be copied to the target environment +and be run without any dependency problems. +In order to provide a usable cross compilation framework for PyPy, +Scratchbox and the Maemo SDK are required. While the former provides +a framework for reproducibly building software packages through +the definition of target profiles and so called devkits, the latter +one provides a set of targets and rootstraps for the compilation +of applications that work on Maemo powered devices. -Variant 0: cross-compiling pypy-c +The Maemo SDK can be downloaded on http://maemo.org/development/sdks/ +You can find all relevant downloads on the referenced pages. + +Before you can start the installation, you need to decide which Maemo +version you need. This mostly depends on the installed version on the +device. We assume that you are running Maemo 4.1. URLs referring to files +in this document will therefore hardcode this version. Just as an example, +the Nokia n810 is shipped with a Maemo 4.0 installation, so 4.1 will not fit. + +In order to get a working SDK environment, you need the file +INSTALL.txt which explains the installation of the Maemo +development environment. You can find the one for Maemo 4.1 here: +http://tablets-dev.nokia.com/4.1/INSTALL.txt + +This document only refers to sections in INSTALL.txt but does not reproduce +all details. + + +Doing it sanely +----------------------------------- + +Installing Scratchbox ++++++++++++++++++++++ + +First of all, Scratchbox needs to be installed. This is done as ``root``. +The installation can be done using an installer script, packages supplied +by the particular linux distribution or manually. Details can be found in section 1 +of the file INSTALL.txt. The URL of the installer is:: + + http://tablets-dev.nokia.com/4.1/maemo-scratchbox-install_4.1.sh + +The script will automatically select the necessary devkits and toolchains +and even automatically use Debian packages on Debian based machines. + +Additional important steps include fixing the mmap and vdso settings +of the kernel (cf. section 1.3), +and the addition of your user account to a special group +(by supplying ``-u YOURUSERNAME`` to the installation script). + +Note that the usage of the Debian devkits and related manually +engineered target profiles is neither sufficient nor useful to provide +applications for Maemo based devices compared to using the automatic +target profile setup provided by the Maemo SDK. Therefore it is +necessary to also install the Maemo SDK as explained next. + + +Installing the Maemo SDK +++++++++++++++++++++++++ + +Afterwards, the Maemo SDK needs to be installed. This is done as a +normal system user (the one that you added to the ``sbox`` group +explained above). One obvious result is that every system user +has his own set of Scratchbox targets. + +It is strongly recommended to do the installation by executing the +script as explained in section 2.1. The URL of the script is:: + + http://tablets-dev.nokia.com/4.1/maemo-sdk-install_4.1.sh + +It will create two new targets and preselect +the target for ARM compilation. This nearly results in a scratchbox environment +that is usable for cross compilation of PyPy. + +The remaining parts of INSTALL.txt describe closed source binaries +and X11 support, we do not need those. + + +Customizing the default targets for PyPy +++++++++++++++++++++++++++++++++++++++++ + +As PyPy does not yet provide a debian package description +file for use on Maemo, we have to install the dependencies manually +in our Scratchbox. The following steps are necessary to accomplish this: + +1. Go into your scratchbox by executing ``/scratchbox/login`` + +1. Add these lines to ``/etc/apt/sources.list``:: + + deb http://repository.maemo.org/extras/ chinook free non-free + deb http://repository.maemo.org/extras-devel/ chinook free non-free + +1. Install these packages to gain full support for extension modules:: + + python-dev, libffi4-dev, libgc-dev, libbz2-dev, zlib1g-dev, libgc-dev XXX check + + This can be done by running ``apt-get update`` and ``apt-get install`` + accordingly. + +1. Leave the scratchbox shell again. + + +Translating PyPy for the Maemo platform ++++++++++++++++++++++++++++++++++++++++ + +Afterwards, you are ready for the translation of RPython programs. +The hosting operating system runs a Python interpreter (at least +2.4) that uses the scratchbox automatically. This is achieved by running +the following command line in the ``pypy/translator/goal`` directory:: + + python translate.py --platform=maemo --opt=mem + +When this step is finished, the ``goal`` directory will contain a binary called +``pypy-c`` which is runnable on the Maemo device. Copy it over to your device +together with ``lib-python`` and the ``pypy/lib`` directory (while preserving +correct paths) and you can start it there. + + + +Variant 0: manual scratchbox ------------------------------------------ -The basic idea is to install a scratchbox environment that emulates -a real ARM-based N810 device. One can then login to this virtual -environment and execute ARM binaries. Scratchbox also provides -compiler toolchains that allow to drive a compiler from the outside. -This is what we want for building pypy-c because most work happens -independently from the platform and we want this work to execute natively. -For all platform relevant details we need to consult the target environment -and use the cross-compiler. So now let's move on to install such an environment -and compiler. - -Note: the - - http://repository.maemo.org/stable/diablo/maemo-scratchbox-install_4.1.1.sh - -script is provided by the maemo team and would automate installation. -Unfortuantely it does not provide a working cross-compiler (XXX -mail to maintainers and see if there is an easy fix). +The stuff below here can be removed in my opinion. -- xoraxax -creating a /scratchbox environment + +Installing scratchbox +++++++++++++++++++++++++++++++++++++++++ The basic idea is to follow @@ -80,91 +181,6 @@ the 'yes' means that the USER gets added to the sbox unix group, neccessary to login into the virtual environment. -Creating an target emulating N810/Maemo environment -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Now we instruct scratchbox to define a target suitable for emulating the -N810/Maemo device: - -Login to the virtual environment and invoke:: - - /scratchbox/login - sb-menu - -this brings up an interactive menu, you need to *setup* a new target, -you may name it "ARMEL" and then you need to select:: - - compiler: cs2007q3-glibc2.5-arm7 - devkits: cputransp, perl, svn - cputransp: (select 'qemu-arm-0.8.2-sb2' when it asks later on) - -In theory, you should also be able to execute the following cmdline:: - - sb-conf setup armel --compiler=cs2007q3-glibc2.5-arm7 \ - --devkit=cputransp:perl:svn \ - --cputransp=qemu-arm-0.8.2-sb2 - -but this did not provide a complete environment for me (XXX try to fix). - -Congrats! If all worked well you should now be able to cross-compile C programs via: - - /scratchbox/compilers/cs2007q3-glibc2.5-arm7/bin/arm-none-linux-gnueabi-gcc - -and copy the binary result to the N810/Maemo device. You can also login to -the virtual environment and execute the ARM binary there. - -XXX [fijal] remember to update that it uses inside gcc these days - -PyPy's translation tool chain tries to use this cross-compiler when -you specify ``--platform=maemo`` to the translate.py script. - -So you can now get yourself a copy of pypy (in the hosting, not the -virtual environment of course!) and do: - - python translate.py --batch --platform=maemo --opt=mem \ - targetpypystandalone.py --no-allworkingmodules - -copy the result to the device and run it. - - -variant 1: Installing `scratchbox`_ -------------------------------------------- - -I had no success with installing scratchbox 2.0, but theoretically it -should work. - -Follow these `installation instructions`_ for 1.0, -make sure that you install cpu-transparency modules, otherwise emulation will -not be available. Preferred toolchain is cs2005q3.2-glibc2.5-arm. - -Follow instructions, running sb-menu and selecting cpu-transparency -method (qemu-arm), devkits (debian-lenny, cpu-transparency) and install files -(and not a rootstrap). - -I had to manually edit /scratchbox/devkits/debian-etch/etc/environment -to add ARCH=armel, otherwise apt-get did not work. I also edited -/etc/apt/sources.list to contain:: - - deb ftp://ftp.fi.debian.org/debian/ lenny main contrib non-free - deb-src ftp://ftp.fi.debian.org/debian/ lenny main contrib non-free - -Then run ``apt-get update``, get an error, ignore it, and run -``fakeroot apt-get install python-dev``. Doesn't work out of -the box for me; I have actually to install a few pieces at a -time, starting from libc6, sometimes with and sometimes -without the ``fakeroot``. It's quite a mess but in the end I -get a ``python2.5``. - -cross-compiling pypy -+++++++++++++++++++++++++++ - -Run:: - ./translate.py --platform=maemo --opt=mem targetpypystandalone --no-allworkingmodules - -This should create pypy-c which is able to run on top of scratchbox. To run it -you need to copy pypy-c, together with libraries to a place accessible -from inside scratchbox. Default is /scratchbox/users//home/ where - is your user id. variant 2: using official maemo-installs @@ -212,34 +228,13 @@ and follow the README. (a number of steps). -Compiling within scratchbox -++++++++++++++++++++++++++++++++ - -After switching to the virtual environment via ``/scratchbox/login`` -and commands like this:: - - svn co http://codespeak.net/svn/pypy/dist pypy-dist - cd pypy-dist/pypy/translator/goal - python translate.py --batch --opt=mem targetpypystandalone.py --no-allworkingmodules - -one will get (after around 10 hours on a medium intel machine) a working pypy-c. -You can transfer this binary to a real device an compile it there. - -cross-compiling (using scratchbox) -++++++++++++++++++++++++++++++++++++++++++++ - -XXX under investigation. might turn out that a different installation -method suffices. the above is still good for getting a maemo simulation -environment - not much missing to also get a simulated graphical environment -from it. - - .. _`installation instructions`: http://www.scratchbox.org/documentation/user/scratchbox-1.0/html/installdoc.html .. _`scratchbox`: http://scratchbox.org -debian -++++++ + +Using a debian target (not recommended, does not work!) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ in theory we don't need to install debian under scratchbox. in practice though, if we want to run pypy-c with allworkingmodules we need to a way to install From xoraxax at codespeak.net Fri Oct 24 01:41:19 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 24 Oct 2008 01:41:19 +0200 (CEST) Subject: [pypy-svn] r59347 - pypy/trunk/pypy/doc Message-ID: <20081023234119.AA81616A06A@codespeak.net> Author: xoraxax Date: Fri Oct 24 01:41:17 2008 New Revision: 59347 Modified: pypy/trunk/pypy/doc/maemo.txt Log: Update maemo.txt Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Fri Oct 24 01:41:17 2008 @@ -76,7 +76,10 @@ http://tablets-dev.nokia.com/4.1/maemo-sdk-install_4.1.sh -It will create two new targets and preselect +It is useful to select the debug packages when being asked (this is +the default). Closed source nokia binaries are not necessary. + +The SDK installation will create two new targets and preselect the target for ARM compilation. This nearly results in a scratchbox environment that is usable for cross compilation of PyPy. @@ -93,17 +96,19 @@ 1. Go into your scratchbox by executing ``/scratchbox/login`` -1. Add these lines to ``/etc/apt/sources.list``:: +1. Add these lines to ``/etc/apt/sources.list`` and replace DIST + by the appropriate name of your Maemo version (chinook or diablo):: - deb http://repository.maemo.org/extras/ chinook free non-free - deb http://repository.maemo.org/extras-devel/ chinook free non-free + deb http://repository.maemo.org/extras/ DIST free non-free + deb http://repository.maemo.org/extras-devel/ DIST free non-free 1. Install these packages to gain full support for extension modules:: - python-dev, libffi4-dev, libgc-dev, libbz2-dev, zlib1g-dev, libgc-dev XXX check + python2.5-dev libffi4-dev libgc-dev This can be done by running ``apt-get update`` and ``apt-get install`` - accordingly. + accordingly. The latter is only needed if you decide to use the Boehm + garbage collector (in fact, it is only available starting from Diablo). 1. Leave the scratchbox shell again. @@ -179,6 +184,7 @@ /scratchbox/sbin/sbox_adduser USER yes the 'yes' means that the USER gets added to the sbox unix group, neccessary to login into the virtual environment. +the 'yes' means that the USER gets added to the sbox unix group, neccessary to login into the virtual environment. From xoraxax at codespeak.net Fri Oct 24 01:45:19 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 24 Oct 2008 01:45:19 +0200 (CEST) Subject: [pypy-svn] r59348 - pypy/trunk/pypy/doc Message-ID: <20081023234519.5391E16A0D2@codespeak.net> Author: xoraxax Date: Fri Oct 24 01:45:18 2008 New Revision: 59348 Modified: pypy/trunk/pypy/doc/maemo.txt Log: Reword paragraph. Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Fri Oct 24 01:45:18 2008 @@ -117,8 +117,10 @@ +++++++++++++++++++++++++++++++++++++++ Afterwards, you are ready for the translation of RPython programs. -The hosting operating system runs a Python interpreter (at least -2.4) that uses the scratchbox automatically. This is achieved by running +Like in a normal PyPy translation run, your Python interpreter on +the hosting operation system runs the translator. And the translator +itself uses the Scratchbox environment to obtain native target +binaries. This is achieved by running the following command line in the ``pypy/translator/goal`` directory:: python translate.py --platform=maemo --opt=mem From pypy-svn at codespeak.net Fri Oct 24 07:23:04 2008 From: pypy-svn at codespeak.net (pypy-svn at codespeak.net) Date: Fri, 24 Oct 2008 07:23:04 +0200 (CEST) Subject: VIAGRA ® Official Site Message-ID: <20081024182235.70864.qmail@cc35x2.sels.ru> An HTML attachment was scrubbed... URL: From antocuni at codespeak.net Fri Oct 24 11:16:13 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 24 Oct 2008 11:16:13 +0200 (CEST) Subject: [pypy-svn] r59353 - pypy/trunk/pypy/doc/config Message-ID: <20081024091613.20C1E16A0CB@codespeak.net> Author: antocuni Date: Fri Oct 24 11:16:12 2008 New Revision: 59353 Added: pypy/trunk/pypy/doc/config/objspace.timing.txt (contents, props changed) pypy/trunk/pypy/doc/config/translation.dump_static_data_info.txt (contents, props changed) pypy/trunk/pypy/doc/config/translation.platform.txt (contents, props changed) Log: document the three new options Added: pypy/trunk/pypy/doc/config/objspace.timing.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/config/objspace.timing.txt Fri Oct 24 11:16:12 2008 @@ -0,0 +1 @@ +timing of various parts of the interpreter (simple profiling) Added: pypy/trunk/pypy/doc/config/translation.dump_static_data_info.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/config/translation.dump_static_data_info.txt Fri Oct 24 11:16:12 2008 @@ -0,0 +1,3 @@ +Dump information about static prebuilt constants, to the file +TARGETNAME.staticdata.info in the /tmp/usession-... directory. This file can +be later inspected using the script ``bin/reportstaticdata.py``. Added: pypy/trunk/pypy/doc/config/translation.platform.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/config/translation.platform.txt Fri Oct 24 11:16:12 2008 @@ -0,0 +1 @@ +select the target platform, in case of cross-compilation From antocuni at codespeak.net Fri Oct 24 11:18:29 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 24 Oct 2008 11:18:29 +0200 (CEST) Subject: [pypy-svn] r59354 - pypy/trunk/pypy/lang/gameboy Message-ID: <20081024091829.54AEE16A22E@codespeak.net> Author: antocuni Date: Fri Oct 24 11:18:28 2008 New Revision: 59354 Modified: pypy/trunk/pypy/lang/gameboy/gameboy_implementation.py Log: remove tabs Modified: pypy/trunk/pypy/lang/gameboy/gameboy_implementation.py ============================================================================== --- pypy/trunk/pypy/lang/gameboy/gameboy_implementation.py (original) +++ pypy/trunk/pypy/lang/gameboy/gameboy_implementation.py Fri Oct 24 11:18:28 2008 @@ -36,20 +36,20 @@ self.is_running = True try: while self.is_running: - self.emulate_cycle() + self.emulate_cycle() except Exception, error: self.is_running = False self.handle_execution_error(error) return 0 def emulate_cycle(self): - self.handle_events() - self.emulate(constants.GAMEBOY_CLOCK >> 2) - RSDL.Delay(1) + self.handle_events() + self.emulate(constants.GAMEBOY_CLOCK >> 2) + RSDL.Delay(1) def handle_execution_error(self, error): - lltype.free(self.event, flavor='raw') - RSDL.Quit() + lltype.free(self.event, flavor='raw') + RSDL.Quit() def handle_events(self): self.poll_event() From fijal at codespeak.net Fri Oct 24 14:11:29 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 14:11:29 +0200 (CEST) Subject: [pypy-svn] r59358 - pypy/trunk/pypy/doc Message-ID: <20081024121129.7CAE616A1C9@codespeak.net> Author: fijal Date: Fri Oct 24 14:11:26 2008 New Revision: 59358 Modified: pypy/trunk/pypy/doc/maemo.txt Log: Two more packages Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Fri Oct 24 14:11:26 2008 @@ -104,7 +104,7 @@ 1. Install these packages to gain full support for extension modules:: - python2.5-dev libffi4-dev libgc-dev + python2.5-dev libffi4-dev libgc-dev zlib1g-dev libbz2-dev This can be done by running ``apt-get update`` and ``apt-get install`` accordingly. The latter is only needed if you decide to use the Boehm From fijal at codespeak.net Fri Oct 24 14:12:09 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 14:12:09 +0200 (CEST) Subject: [pypy-svn] r59359 - pypy/trunk/pypy/doc Message-ID: <20081024121209.DF7D716A294@codespeak.net> Author: fijal Date: Fri Oct 24 14:12:09 2008 New Revision: 59359 Modified: pypy/trunk/pypy/doc/maemo.txt Log: Change order for latter text to make sense Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Fri Oct 24 14:12:09 2008 @@ -104,7 +104,7 @@ 1. Install these packages to gain full support for extension modules:: - python2.5-dev libffi4-dev libgc-dev zlib1g-dev libbz2-dev + python2.5-dev libffi4-dev zlib1g-dev libbz2-dev libgc-dev This can be done by running ``apt-get update`` and ``apt-get install`` accordingly. The latter is only needed if you decide to use the Boehm From fijal at codespeak.net Fri Oct 24 14:13:34 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 14:13:34 +0200 (CEST) Subject: [pypy-svn] r59360 - pypy/trunk/pypy/doc Message-ID: <20081024121334.7A29616A2A5@codespeak.net> Author: fijal Date: Fri Oct 24 14:13:34 2008 New Revision: 59360 Modified: pypy/trunk/pypy/doc/maemo.txt Log: add an XXX Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Fri Oct 24 14:13:34 2008 @@ -125,6 +125,10 @@ python translate.py --platform=maemo --opt=mem +XXX IMO this needs either a) cleaner explanation b) a script that does that +XXX [creates correct directory to be copied]. "Together with correct path +XXX sounds a bit vague [fijal] + When this step is finished, the ``goal`` directory will contain a binary called ``pypy-c`` which is runnable on the Maemo device. Copy it over to your device together with ``lib-python`` and the ``pypy/lib`` directory (while preserving From fijal at codespeak.net Fri Oct 24 14:33:04 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 14:33:04 +0200 (CEST) Subject: [pypy-svn] r59362 - in pypy/trunk/lib-python: 2.4.1 modified-2.4.1 Message-ID: <20081024123304.2658216A20D@codespeak.net> Author: fijal Date: Fri Oct 24 14:33:02 2008 New Revision: 59362 Removed: pypy/trunk/lib-python/2.4.1/ pypy/trunk/lib-python/modified-2.4.1/ Log: Remove 2.4 library From fijal at codespeak.net Fri Oct 24 15:32:53 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 15:32:53 +0200 (CEST) Subject: [pypy-svn] r59365 - pypy/build/bot2/pypybuildbot/test Message-ID: <20081024133253.DF56516A2DB@codespeak.net> Author: fijal Date: Fri Oct 24 15:32:49 2008 New Revision: 59365 Added: pypy/build/bot2/pypybuildbot/test/__init__.py (contents, props changed) Log: this one is needed Added: pypy/build/bot2/pypybuildbot/test/__init__.py ============================================================================== From fijal at codespeak.net Fri Oct 24 15:37:15 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 15:37:15 +0200 (CEST) Subject: [pypy-svn] r59366 - pypy/build/bot2/pypybuildbot Message-ID: <20081024133715.EE74716A2B4@codespeak.net> Author: fijal Date: Fri Oct 24 15:37:15 2008 New Revision: 59366 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: add one build for scratchbox Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Oct 24 15:37:15 2008 @@ -119,3 +119,15 @@ "--pypy=pypy/translator/goal/pypy-c", "--resultlog=cpython.log", "lib-python"], logfiles={'pytestLog': 'cpython.log'})) + +class PyPyTranslatedScratchbox(factory.BuildFactory): + def __init__(self, *a, **kw): + platform = kw.pop('platform', 'linux') + + factory.BuildFactory.__init__(self, *a, **kw) + + setup_steps(platform, self) + + self.addStep(Translate(["--platform maemo", "-Omem"], [])) + # right now we stop here, this is mostly a copy of what was + # before, try to share more code From fijal at codespeak.net Fri Oct 24 15:45:07 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 15:45:07 +0200 (CEST) Subject: [pypy-svn] r59367 - pypy/build/bot2/pypybuildbot Message-ID: <20081024134507.CCDA616A2D6@codespeak.net> Author: fijal Date: Fri Oct 24 15:45:07 2008 New Revision: 59367 Modified: pypy/build/bot2/pypybuildbot/builds.py pypy/build/bot2/pypybuildbot/master.py Log: add a builder for scratchbox Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Oct 24 15:45:07 2008 @@ -120,7 +120,7 @@ "--resultlog=cpython.log", "lib-python"], logfiles={'pytestLog': 'cpython.log'})) -class PyPyTranslatedScratchbox(factory.BuildFactory): +class PyPyTranslatedScratchboxTestFactory(factory.BuildFactory): def __init__(self, *a, **kw): platform = kw.pop('platform', 'linux') Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Oct 24 15:45:07 2008 @@ -27,12 +27,14 @@ pypyTranslatedLibPythonTestFactory = pypybuilds.PyPyTranslaledLibPythonTestFactory() pypyTranslatedLibPythonTestFactoryWin = pypybuilds.PyPyTranslaledLibPythonTestFactory(platform="win32") +pypyTranslatedLibPythonMaemoTestFactory = pypybuilds.PyPyTranslatedScratchboxTestFactory() LINUX32 = "own-linux-x86-32" CPYLINUX32 = "pypy-c-lib-python-linux-x86-32" CPYWIN32 = "pypy-c-lib-python-win-32" CPYLINUX32_VM = 'pypy-c-lib-python-linux-x86-32vm' +CPYMAEMO = "pypy-c-lib-python-maemo" BuildmasterConfig = { 'slavePortnum': slavePortnum, @@ -67,7 +69,11 @@ "slavenames": ["winxp32-py2.5"], "builddir": CPYWIN32, "factory": pypyTranslatedLibPythonTestFactoryWin - }, + }, + {"name" : CPYMAEMO, + "slavenames": ['bigdogvm1'], + "builddir" : CPYMAEMO, + "factory": pypyTranslatedLibPythonMaemoTestFactory, ], 'buildbotURL': 'http://codespeak.net:%d/'%(httpPortNumber), From fijal at codespeak.net Fri Oct 24 15:46:24 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 15:46:24 +0200 (CEST) Subject: [pypy-svn] r59368 - pypy/build/bot2/pypybuildbot Message-ID: <20081024134624.ABB8516A2BC@codespeak.net> Author: fijal Date: Fri Oct 24 15:46:24 2008 New Revision: 59368 Modified: pypy/build/bot2/pypybuildbot/master.py Log: fix syntax error. i want tests to at least import this file.. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Oct 24 15:46:24 2008 @@ -74,6 +74,7 @@ "slavenames": ['bigdogvm1'], "builddir" : CPYMAEMO, "factory": pypyTranslatedLibPythonMaemoTestFactory, + }, ], 'buildbotURL': 'http://codespeak.net:%d/'%(httpPortNumber), From fijal at codespeak.net Fri Oct 24 16:12:06 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 16:12:06 +0200 (CEST) Subject: [pypy-svn] r59369 - pypy/trunk/pypy/rpython/memory/gc Message-ID: <20081024141206.270DB16A2CD@codespeak.net> Author: fijal Date: Fri Oct 24 16:12:05 2008 New Revision: 59369 Modified: pypy/trunk/pypy/rpython/memory/gc/markcompact.py Log: * Don't raw_malloc pieces for tid_backup, instead keep them at the end of space * Couple of cleanups. * Use USHORT for typeid Modified: pypy/trunk/pypy/rpython/memory/gc/markcompact.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/markcompact.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/markcompact.py Fri Oct 24 16:12:05 2008 @@ -11,6 +11,7 @@ from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.objectmodel import we_are_translated +from pypy.rpython.lltypesystem import rffi TYPEID_MASK = 0xffff0000 first_gcflag = 2 @@ -63,9 +64,12 @@ # XXX adjust GC_CLEARANCE = 32*1024 +TID_TYPE = rffi.USHORT +BYTES_PER_TID = rffi.sizeof(TID_TYPE) + class MarkCompactGC(MovingGCBase): HDR = lltype.Struct('header', ('forward_ptr', llmemory.Address)) - TID_BACKUP = lltype.Array(lltype.Signed) + TID_BACKUP = lltype.Array(TID_TYPE, hints={'nolength':True}) WEAKREF_OFFSETS = lltype.Array(lltype.Signed) @@ -162,8 +166,10 @@ return True def new_space_size(self, occupied, needed): - return (occupied * FREE_SPACE_MULTIPLIER / - FREE_SPACE_DIVIDER + FREE_SPACE_ADD + needed) + res = (occupied * FREE_SPACE_MULTIPLIER / + FREE_SPACE_DIVIDER + FREE_SPACE_ADD + needed) + # align it to 4096, which is somewhat around page size + return ((res/4096) + 1) * 4096 def double_space_size(self, minimal_size): while self.space_size <= minimal_size: @@ -203,12 +209,23 @@ self.to_see.delete() num_of_alive_objs = self.compute_alive_objects() size_of_alive_objs = self.totalsize_of_objs - totalsize = self.new_space_size(size_of_alive_objs, needed) + totalsize = self.new_space_size(size_of_alive_objs, needed + + num_of_alive_objs * BYTES_PER_TID) + tid_backup_size = (llmemory.sizeof(self.TID_BACKUP, 0) + + llmemory.sizeof(TID_TYPE) * num_of_alive_objs) if totalsize >= self.space_size: toaddr = self.double_space_size(totalsize) + llarena.arena_reserve(toaddr + size_of_alive_objs, tid_backup_size) + self.tid_backup = llmemory.cast_adr_to_ptr( + toaddr + size_of_alive_objs, + lltype.Ptr(self.TID_BACKUP)) resizing = True else: toaddr = llarena.arena_new_view(self.space) + llarena.arena_reserve(self.top_of_space, tid_backup_size) + self.tid_backup = llmemory.cast_adr_to_ptr( + self.top_of_space, + lltype.Ptr(self.TID_BACKUP)) resizing = False self.next_collect_after = totalsize weakref_offsets = self.collect_weakref_offsets() @@ -228,11 +245,12 @@ # because we free stuff already in raw_memmove, we # would get double free here. Let's free it anyway llarena.arena_free(self.space) + llarena.arena_reset(toaddr + size_of_alive_objs, tid_backup_size, + True) self.space = toaddr self.free = finaladdr self.top_of_space = toaddr + self.next_collect_after self.debug_check_consistency() - lltype.free(self.tid_backup, flavor='raw') self.tid_backup = lltype.nullptr(self.TID_BACKUP) if self.run_finalizers.non_empty(): self.execute_finalizers() @@ -341,10 +359,6 @@ def update_forward_pointers(self, toaddr, num_of_alive_objs): fromaddr = self.space size_gc_header = self.gcheaderbuilder.size_gc_header - # XXX one can adjust this not to keep word per object, but instead - # just number of used bits - self.tid_backup = lltype.malloc(self.TID_BACKUP, num_of_alive_objs, - flavor='raw') i = 0 while fromaddr < self.free: hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR)) @@ -443,10 +457,10 @@ return self.header(obj).forward_ptr != NULL def backup_typeid(self, num, obj): - self.tid_backup[num] = self.get_type_id(obj) + self.tid_backup[num] = rffi.cast(rffi.USHORT, self.get_type_id(obj)) def get_typeid_from_backup(self, num): - return self.tid_backup[num] + return rffi.cast(lltype.Signed, self.tid_backup[num]) def get_size_from_backup(self, obj, num): typeid = self.get_typeid_from_backup(num) From fijal at codespeak.net Fri Oct 24 16:20:03 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 16:20:03 +0200 (CEST) Subject: [pypy-svn] r59370 - pypy/build/bot2/pypybuildbot Message-ID: <20081024142003.F34D316A2DA@codespeak.net> Author: fijal Date: Fri Oct 24 16:20:03 2008 New Revision: 59370 Modified: pypy/build/bot2/pypybuildbot/builds.py pypy/build/bot2/pypybuildbot/master.py Log: Rename translaled to translated Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Oct 24 16:20:03 2008 @@ -103,7 +103,7 @@ timeout = 2400, env={"PYTHONPATH": ['.']})) -class PyPyTranslaledLibPythonTestFactory(factory.BuildFactory): +class PyPyTranslatedLibPythonTestFactory(factory.BuildFactory): def __init__(self, *a, **kw): platform = kw.pop('platform', 'linux') Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Oct 24 16:20:03 2008 @@ -25,8 +25,8 @@ pypyOwnTestFactory = pypybuilds.PyPyOwnTestFactory() pypyOwnTestFactoryWin = pypybuilds.PyPyOwnTestFactory(platform="win32") -pypyTranslatedLibPythonTestFactory = pypybuilds.PyPyTranslaledLibPythonTestFactory() -pypyTranslatedLibPythonTestFactoryWin = pypybuilds.PyPyTranslaledLibPythonTestFactory(platform="win32") +pypyTranslatedLibPythonTestFactory = pypybuilds.PyPyTranslatedLibPythonTestFactory() +pypyTranslatedLibPythonTestFactoryWin = pypybuilds.PyPyTranslatedLibPythonTestFactory(platform="win32") pypyTranslatedLibPythonMaemoTestFactory = pypybuilds.PyPyTranslatedScratchboxTestFactory() From fijal at codespeak.net Fri Oct 24 16:23:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 16:23:33 +0200 (CEST) Subject: [pypy-svn] r59371 - pypy/build/bot2/pypybuildbot Message-ID: <20081024142333.EEA2216A2DB@codespeak.net> Author: fijal Date: Fri Oct 24 16:23:33 2008 New Revision: 59371 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: I don't know, add step to run tests maybe? Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Oct 24 16:23:33 2008 @@ -81,7 +81,7 @@ "-p.buildbot-sourcedata", "."], )) factory.addStep(source.SVN(baseURL="http://codespeak.net/svn/pypy/", - defaultBranch="trunk")) + defaultBranch="trunk")) class PyPyOwnTestFactory(factory.BuildFactory): @@ -129,5 +129,10 @@ setup_steps(platform, self) self.addStep(Translate(["--platform maemo", "-Omem"], [])) - # right now we stop here, this is mostly a copy of what was - # before, try to share more code + + self.addStep(ShellCmd( + description="lib-python test", + command=["python", "pypy/test_all.py", + "--pypy=pypy/translator/goal/pypy-c", + "--resultlog=cpython.log", "lib-python"], + logfiles={'pytestLog': 'cpython.log'})) From fijal at codespeak.net Fri Oct 24 16:25:17 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 16:25:17 +0200 (CEST) Subject: [pypy-svn] r59372 - pypy/build/bot2/pypybuildbot Message-ID: <20081024142517.930A616A05D@codespeak.net> Author: fijal Date: Fri Oct 24 16:25:17 2008 New Revision: 59372 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: split args maybe? Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Oct 24 16:25:17 2008 @@ -128,7 +128,7 @@ setup_steps(platform, self) - self.addStep(Translate(["--platform maemo", "-Omem"], [])) + self.addStep(Translate(["--platform", "maemo", "-Omem"], [])) self.addStep(ShellCmd( description="lib-python test", From fijal at codespeak.net Fri Oct 24 16:27:40 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 16:27:40 +0200 (CEST) Subject: [pypy-svn] r59373 - pypy/build/bot2/pypybuildbot Message-ID: <20081024142740.6897D16A0FC@codespeak.net> Author: fijal Date: Fri Oct 24 16:27:40 2008 New Revision: 59373 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: try to remove --platform maemo Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Oct 24 16:27:40 2008 @@ -123,12 +123,11 @@ class PyPyTranslatedScratchboxTestFactory(factory.BuildFactory): def __init__(self, *a, **kw): platform = kw.pop('platform', 'linux') - factory.BuildFactory.__init__(self, *a, **kw) setup_steps(platform, self) - self.addStep(Translate(["--platform", "maemo", "-Omem"], [])) + self.addStep(Translate(["-Omem"], [])) self.addStep(ShellCmd( description="lib-python test", From fijal at codespeak.net Fri Oct 24 16:46:53 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 16:46:53 +0200 (CEST) Subject: [pypy-svn] r59374 - pypy/build/bot2/pypybuildbot Message-ID: <20081024144653.B691316A28B@codespeak.net> Author: fijal Date: Fri Oct 24 16:46:51 2008 New Revision: 59374 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Adapt for cmd being possibly None Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Oct 24 16:46:51 2008 @@ -7,7 +7,7 @@ # our own version that can distinguish abort cases (rc == -1) def getText(self, cmd, results): - if cmd.rc == -1: + if cmd is not None and cmd.rc == -1: return self.describe(True) + ['aborted'] return shell.ShellCommand.getText(self, cmd, results) @@ -127,7 +127,7 @@ setup_steps(platform, self) - self.addStep(Translate(["-Omem"], [])) + self.addStep(Translate(["--platform", "maemo", "-Omem"], [])) self.addStep(ShellCmd( description="lib-python test", From arigo at codespeak.net Fri Oct 24 16:47:38 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 24 Oct 2008 16:47:38 +0200 (CEST) Subject: [pypy-svn] r59375 - pypy/branch/oo-jit/pypy/jit/rainbow Message-ID: <20081024144738.9382116A28B@codespeak.net> Author: arigo Date: Fri Oct 24 16:47:38 2008 New Revision: 59375 Modified: pypy/branch/oo-jit/pypy/jit/rainbow/rhotpath.py Log: Remove a strange import. This speeds up some tests because importing i386 causes a lot of work in setting up multimethod tables :-( Modified: pypy/branch/oo-jit/pypy/jit/rainbow/rhotpath.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/rainbow/rhotpath.py (original) +++ pypy/branch/oo-jit/pypy/jit/rainbow/rhotpath.py Fri Oct 24 16:47:38 2008 @@ -2,7 +2,6 @@ RPython support code for the hotpath policy. """ -from pypy.jit.codegen.i386.rgenop import cast_whatever_to_int from pypy.jit.timeshifter import rtimeshift, rvalue from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.rpython.annlowlevel import cachedtype, base_ptr_lltype @@ -75,6 +74,15 @@ gv_exitfnptr, args_gv) leave_graph(interp) + at specialize.arg(0) +def cast_whatever_to_int(T, value): + if isinstance(T, lltype.Ptr): + return lltype.cast_ptr_to_int(value) + elif T is llmemory.Address: + return llmemory.cast_adr_to_int(value) + else: + return lltype.cast_primitive(lltype.Signed, value) + # ____________________________________________________________ class FinishedCompiling(Exception): From fijal at codespeak.net Fri Oct 24 17:16:04 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 17:16:04 +0200 (CEST) Subject: [pypy-svn] r59378 - in pypy/trunk/pypy: annotation/test bin config doc/config interpreter/astcompiler/test lang/gameboy/tool lang/js lang/prolog/interpreter lang/scheme lang/smalltalk/tool lib/test2 module/__builtin__/test module/_codecs/test module/_file/test module/_sre/test module/sys/test objspace/std/test rlib/parsing/test rlib/rsdl/test rpython/microbench tool tool/algo/test tool/pytest tool/test translator translator/benchmark translator/c translator/c/test translator/cli/test translator/goal translator/goal/test2 translator/js translator/js/examples translator/js/examples/bnb translator/microbench/pybench translator/sandbox translator/sandbox/test translator/test translator/tool Message-ID: <20081024151604.9C95216A298@codespeak.net> Author: fijal Date: Fri Oct 24 17:16:02 2008 New Revision: 59378 Modified: pypy/trunk/pypy/annotation/test/autopath.py pypy/trunk/pypy/bin/autopath.py pypy/trunk/pypy/config/autopath.py pypy/trunk/pypy/doc/config/autopath.py pypy/trunk/pypy/interpreter/astcompiler/test/stdlib_testall.py pypy/trunk/pypy/lang/gameboy/tool/autopath.py pypy/trunk/pypy/lang/js/autopath.py pypy/trunk/pypy/lang/prolog/interpreter/autopath.py pypy/trunk/pypy/lang/scheme/autopath.py pypy/trunk/pypy/lang/smalltalk/tool/autopath.py pypy/trunk/pypy/lib/test2/autopath.py pypy/trunk/pypy/module/__builtin__/test/autopath.py pypy/trunk/pypy/module/__builtin__/test/test_buffer.py pypy/trunk/pypy/module/_codecs/test/autopath.py pypy/trunk/pypy/module/_file/test/test_file_extra.py pypy/trunk/pypy/module/_sre/test/autopath.py pypy/trunk/pypy/module/sys/test/autopath.py pypy/trunk/pypy/objspace/std/test/test_complexobject.py pypy/trunk/pypy/objspace/std/test/test_set.py pypy/trunk/pypy/rlib/parsing/test/autopath.py pypy/trunk/pypy/rlib/rsdl/test/autopath.py pypy/trunk/pypy/rpython/microbench/autopath.py pypy/trunk/pypy/tool/algo/test/autopath.py pypy/trunk/pypy/tool/autopath.py pypy/trunk/pypy/tool/pytest/autopath.py pypy/trunk/pypy/tool/stdlib_opcode.py pypy/trunk/pypy/tool/test/autopath.py pypy/trunk/pypy/translator/autopath.py pypy/trunk/pypy/translator/benchmark/autopath.py pypy/trunk/pypy/translator/benchmark/benchmarks.py pypy/trunk/pypy/translator/c/autopath.py pypy/trunk/pypy/translator/c/test/autopath.py pypy/trunk/pypy/translator/cli/test/autopath.py pypy/trunk/pypy/translator/goal/autopath.py pypy/trunk/pypy/translator/goal/test2/autopath.py pypy/trunk/pypy/translator/js/autopath.py pypy/trunk/pypy/translator/js/examples/autopath.py pypy/trunk/pypy/translator/js/examples/bnb/autopath.py pypy/trunk/pypy/translator/microbench/pybench/autopath.py pypy/trunk/pypy/translator/sandbox/autopath.py pypy/trunk/pypy/translator/sandbox/test/autopath.py pypy/trunk/pypy/translator/sandbox/test/test_pypy_interact.py pypy/trunk/pypy/translator/test/autopath.py pypy/trunk/pypy/translator/tool/autopath.py Log: Change 2.4.1 to 2.5.2. Add a new dir in autopath. Modified: pypy/trunk/pypy/annotation/test/autopath.py ============================================================================== --- pypy/trunk/pypy/annotation/test/autopath.py (original) +++ pypy/trunk/pypy/annotation/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/bin/autopath.py ============================================================================== --- pypy/trunk/pypy/bin/autopath.py (original) +++ pypy/trunk/pypy/bin/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/config/autopath.py ============================================================================== --- pypy/trunk/pypy/config/autopath.py (original) +++ pypy/trunk/pypy/config/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/doc/config/autopath.py ============================================================================== --- pypy/trunk/pypy/doc/config/autopath.py (original) +++ pypy/trunk/pypy/doc/config/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/interpreter/astcompiler/test/stdlib_testall.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/test/stdlib_testall.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/test/stdlib_testall.py Fri Oct 24 17:16:02 2008 @@ -1,4 +1,4 @@ -import pypy +from pypy.toolautopath import libpythondir import py from pypy.interpreter.astcompiler.test.test_compiler import \ compile_with_astcompiler @@ -12,8 +12,7 @@ compile_with_astcompiler(source, mode='exec', space=space) def test_all(self): - p = py.path.local(pypy.__file__).dirpath().dirpath('lib-python', - '2.4.1') + p = py.path.local(libpythondir) files = p.listdir("*.py") files.sort() for s in files: Modified: pypy/trunk/pypy/lang/gameboy/tool/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/gameboy/tool/autopath.py (original) +++ pypy/trunk/pypy/lang/gameboy/tool/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/lang/js/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/js/autopath.py (original) +++ pypy/trunk/pypy/lang/js/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/lang/prolog/interpreter/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/prolog/interpreter/autopath.py (original) +++ pypy/trunk/pypy/lang/prolog/interpreter/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/lang/scheme/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/scheme/autopath.py (original) +++ pypy/trunk/pypy/lang/scheme/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/lang/smalltalk/tool/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/smalltalk/tool/autopath.py (original) +++ pypy/trunk/pypy/lang/smalltalk/tool/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/lib/test2/autopath.py ============================================================================== --- pypy/trunk/pypy/lib/test2/autopath.py (original) +++ pypy/trunk/pypy/lib/test2/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/module/__builtin__/test/autopath.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/test/autopath.py (original) +++ pypy/trunk/pypy/module/__builtin__/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/module/__builtin__/test/test_buffer.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/test/test_buffer.py (original) +++ pypy/trunk/pypy/module/__builtin__/test/test_buffer.py Fri Oct 24 17:16:02 2008 @@ -1,5 +1,5 @@ """Tests some behaviour of the buffer type that is not tested in -lib-python/2.4.1/test/test_types.py where the stdlib buffer tests live.""" +lib-python/2.5.2/test/test_types.py where the stdlib buffer tests live.""" import autopath class AppTestBuffer: Modified: pypy/trunk/pypy/module/_codecs/test/autopath.py ============================================================================== --- pypy/trunk/pypy/module/_codecs/test/autopath.py (original) +++ pypy/trunk/pypy/module/_codecs/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/module/_file/test/test_file_extra.py ============================================================================== --- pypy/trunk/pypy/module/_file/test/test_file_extra.py (original) +++ pypy/trunk/pypy/module/_file/test/test_file_extra.py Fri Oct 24 17:16:02 2008 @@ -525,7 +525,7 @@ def test_weakref_dies_before_file_closes(self): # Hard-to-reproduce failure (which should now be fixed). - # I think that this is how lib-python/modified-2.4.1/test_file.py + # I think that this is how lib-python/modified-2.5.2/test_file.py # sometimes failed on a Boehm pypy-c. import weakref, gc fn = self.temptestfile Modified: pypy/trunk/pypy/module/_sre/test/autopath.py ============================================================================== --- pypy/trunk/pypy/module/_sre/test/autopath.py (original) +++ pypy/trunk/pypy/module/_sre/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/module/sys/test/autopath.py ============================================================================== --- pypy/trunk/pypy/module/sys/test/autopath.py (original) +++ pypy/trunk/pypy/module/sys/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/objspace/std/test/test_complexobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_complexobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_complexobject.py Fri Oct 24 17:16:02 2008 @@ -73,7 +73,7 @@ h = self.helper from random import random # XXX this test passed but took waaaaay to long - # look at dist/lib-python/modified-2.4.1/test/test_complex.py + # look at dist/lib-python/modified-2.5.2/test/test_complex.py #simple_real = [float(i) for i in xrange(-5, 6)] simple_real = [-2.0, 0.0, 1.0] simple_complex = [complex(x, y) for x in simple_real for y in simple_real] Modified: pypy/trunk/pypy/objspace/std/test/test_set.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_set.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_set.py Fri Oct 24 17:16:02 2008 @@ -1,7 +1,7 @@ """ The main test for the set implementation is located at: - pypy-dist/lib-python/modified-2.4.1/test/test_set.py + pypy-dist/lib-python/modified-2.5.2/test/test_set.py go there and invoke ../../../pypy/bin/py.py test_set.py This file just contains some basic tests that make sure, the implementation Modified: pypy/trunk/pypy/rlib/parsing/test/autopath.py ============================================================================== --- pypy/trunk/pypy/rlib/parsing/test/autopath.py (original) +++ pypy/trunk/pypy/rlib/parsing/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/rlib/rsdl/test/autopath.py ============================================================================== --- pypy/trunk/pypy/rlib/rsdl/test/autopath.py (original) +++ pypy/trunk/pypy/rlib/rsdl/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/rpython/microbench/autopath.py ============================================================================== --- pypy/trunk/pypy/rpython/microbench/autopath.py (original) +++ pypy/trunk/pypy/rpython/microbench/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/tool/algo/test/autopath.py ============================================================================== --- pypy/trunk/pypy/tool/algo/test/autopath.py (original) +++ pypy/trunk/pypy/tool/algo/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/tool/autopath.py ============================================================================== --- pypy/trunk/pypy/tool/autopath.py (original) +++ pypy/trunk/pypy/tool/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/tool/pytest/autopath.py ============================================================================== --- pypy/trunk/pypy/tool/pytest/autopath.py (original) +++ pypy/trunk/pypy/tool/pytest/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/tool/stdlib_opcode.py ============================================================================== --- pypy/trunk/pypy/tool/stdlib_opcode.py (original) +++ pypy/trunk/pypy/tool/stdlib_opcode.py Fri Oct 24 17:16:02 2008 @@ -6,7 +6,7 @@ def load_opcode(): import py - opcode_path = py.path.local(__file__).dirpath().dirpath().dirpath('lib-python/modified-2.4.1/opcode.py') + opcode_path = py.path.local(__file__).dirpath().dirpath().dirpath('lib-python/modified-2.5.2/opcode.py') d = {} execfile(str(opcode_path), d) return d Modified: pypy/trunk/pypy/tool/test/autopath.py ============================================================================== --- pypy/trunk/pypy/tool/test/autopath.py (original) +++ pypy/trunk/pypy/tool/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/autopath.py (original) +++ pypy/trunk/pypy/translator/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/benchmark/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/autopath.py (original) +++ pypy/trunk/pypy/translator/benchmark/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/trunk/pypy/translator/benchmark/benchmarks.py Fri Oct 24 17:16:02 2008 @@ -63,8 +63,9 @@ return r def run_pystone(executable='/usr/local/bin/python', n=''): - distdir = py.magic.autopath().dirpath().dirpath().dirpath().dirpath() - pystone = distdir.join('lib-python').join('2.4.1').join('test').join('pystone.py') + from pypy.tool import autopath + distdir = py.path.local(autopath.pypydir).dirpath() + pyston = py.path.local(autopath.libpythondir).join('test', 'pystone.py') txt = run_cmd('"%s" "%s" %s' % (executable, pystone, n)) return get_result(txt, PYSTONE_PATTERN) Modified: pypy/trunk/pypy/translator/c/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/c/autopath.py (original) +++ pypy/trunk/pypy/translator/c/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/c/test/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/autopath.py (original) +++ pypy/trunk/pypy/translator/c/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/cli/test/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/cli/test/autopath.py (original) +++ pypy/trunk/pypy/translator/cli/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/goal/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/goal/autopath.py (original) +++ pypy/trunk/pypy/translator/goal/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/goal/test2/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/goal/test2/autopath.py (original) +++ pypy/trunk/pypy/translator/goal/test2/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/js/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/js/autopath.py (original) +++ pypy/trunk/pypy/translator/js/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/js/examples/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/js/examples/autopath.py (original) +++ pypy/trunk/pypy/translator/js/examples/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/js/examples/bnb/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/js/examples/bnb/autopath.py (original) +++ pypy/trunk/pypy/translator/js/examples/bnb/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/microbench/pybench/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/microbench/pybench/autopath.py (original) +++ pypy/trunk/pypy/translator/microbench/pybench/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/sandbox/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/autopath.py (original) +++ pypy/trunk/pypy/translator/sandbox/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/sandbox/test/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/test/autopath.py (original) +++ pypy/trunk/pypy/translator/sandbox/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/sandbox/test/test_pypy_interact.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/test/test_pypy_interact.py (original) +++ pypy/trunk/pypy/translator/sandbox/test/test_pypy_interact.py Fri Oct 24 17:16:02 2008 @@ -3,8 +3,7 @@ from pypy.translator.sandbox.pypy_interact import PyPySandboxedProc from pypy.translator.interactive import Translation -SITE_PY_CONTENT = open(os.path.join(autopath.pypydir, os.pardir, - 'lib-python', 'modified-2.4.1', 'site.py'), +SITE_PY_CONTENT = open(os.path.join(autopath.libpythonmodifieddir, 'site.py'), 'rb').read() ERROR_TEXT = os.strerror(errno.ENOENT) @@ -25,7 +24,7 @@ assert_(argv[0] == '/bin/pypy-c', "bad argv[0]") st = os.lstat('/bin/pypy-c') assert_(stat.S_ISREG(st.st_mode), "bad st_mode for /bin/pypy-c") - for dirname in ['/bin/lib-python/2.4.1', '/bin/pypy/lib']: + for dirname in ['/bin/lib-python/2.5.2', '/bin/pypy/lib']: st = os.stat(dirname) assert_(stat.S_ISDIR(st.st_mode), "bad st_mode for " + dirname) assert_(os.environ.get('PYTHONPATH') is None, "unexpected $PYTHONPATH") @@ -35,9 +34,9 @@ pass else: assert_(False, "os.stat('site') should have failed") - st = os.stat('/bin/lib-python/modified-2.4.1/site.py') + st = os.stat('/bin/lib-python/modified-2.5.2/site.py') assert_(stat.S_ISREG(st.st_mode), "bad st_mode for .../site.py") - fd = os.open('/bin/lib-python/modified-2.4.1/site.py', os.O_RDONLY, 0666) + fd = os.open('/bin/lib-python/modified-2.5.2/site.py', os.O_RDONLY, 0666) length = 8192 ofs = 0 while True: Modified: pypy/trunk/pypy/translator/test/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/test/autopath.py (original) +++ pypy/trunk/pypy/translator/test/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() Modified: pypy/trunk/pypy/translator/tool/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/tool/autopath.py (original) +++ pypy/trunk/pypy/translator/tool/autopath.py Fri Oct 24 17:16:02 2008 @@ -21,6 +21,7 @@ """ +import py def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir @@ -128,6 +129,8 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) +libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) if __name__ == '__main__': __clone() From fijal at codespeak.net Fri Oct 24 17:19:50 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 17:19:50 +0200 (CEST) Subject: [pypy-svn] r59379 - in pypy/trunk/pypy: annotation/test bin config doc/config lang/gameboy/tool lang/js lang/prolog/interpreter lang/scheme lang/smalltalk/tool lib/test2 module/__builtin__/test module/_codecs/test module/_sre/test module/sys/test rlib/parsing/test rlib/rsdl/test rpython/microbench tool tool/algo/test tool/pytest tool/test translator translator/benchmark translator/c translator/c/test translator/cli/test translator/goal translator/goal/test2 translator/js translator/js/examples translator/js/examples/bnb translator/microbench/pybench translator/sandbox translator/sandbox/test translator/test translator/tool Message-ID: <20081024151950.6EE3216A2A6@codespeak.net> Author: fijal Date: Fri Oct 24 17:19:47 2008 New Revision: 59379 Modified: pypy/trunk/pypy/annotation/test/autopath.py pypy/trunk/pypy/bin/autopath.py pypy/trunk/pypy/config/autopath.py pypy/trunk/pypy/doc/config/autopath.py pypy/trunk/pypy/lang/gameboy/tool/autopath.py pypy/trunk/pypy/lang/js/autopath.py pypy/trunk/pypy/lang/prolog/interpreter/autopath.py pypy/trunk/pypy/lang/scheme/autopath.py pypy/trunk/pypy/lang/smalltalk/tool/autopath.py pypy/trunk/pypy/lib/test2/autopath.py pypy/trunk/pypy/module/__builtin__/test/autopath.py pypy/trunk/pypy/module/_codecs/test/autopath.py pypy/trunk/pypy/module/_sre/test/autopath.py pypy/trunk/pypy/module/sys/test/autopath.py pypy/trunk/pypy/rlib/parsing/test/autopath.py pypy/trunk/pypy/rlib/rsdl/test/autopath.py pypy/trunk/pypy/rpython/microbench/autopath.py pypy/trunk/pypy/tool/algo/test/autopath.py pypy/trunk/pypy/tool/autopath.py pypy/trunk/pypy/tool/pytest/autopath.py pypy/trunk/pypy/tool/test/autopath.py pypy/trunk/pypy/translator/autopath.py pypy/trunk/pypy/translator/benchmark/autopath.py pypy/trunk/pypy/translator/c/autopath.py pypy/trunk/pypy/translator/c/test/autopath.py pypy/trunk/pypy/translator/cli/test/autopath.py pypy/trunk/pypy/translator/goal/autopath.py pypy/trunk/pypy/translator/goal/test2/autopath.py pypy/trunk/pypy/translator/js/autopath.py pypy/trunk/pypy/translator/js/examples/autopath.py pypy/trunk/pypy/translator/js/examples/bnb/autopath.py pypy/trunk/pypy/translator/microbench/pybench/autopath.py pypy/trunk/pypy/translator/sandbox/autopath.py pypy/trunk/pypy/translator/sandbox/test/autopath.py pypy/trunk/pypy/translator/test/autopath.py pypy/trunk/pypy/translator/tool/autopath.py Log: fix autopath to import py only *after* sys.path has been augmented Modified: pypy/trunk/pypy/annotation/test/autopath.py ============================================================================== --- pypy/trunk/pypy/annotation/test/autopath.py (original) +++ pypy/trunk/pypy/annotation/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/bin/autopath.py ============================================================================== --- pypy/trunk/pypy/bin/autopath.py (original) +++ pypy/trunk/pypy/bin/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/config/autopath.py ============================================================================== --- pypy/trunk/pypy/config/autopath.py (original) +++ pypy/trunk/pypy/config/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/doc/config/autopath.py ============================================================================== --- pypy/trunk/pypy/doc/config/autopath.py (original) +++ pypy/trunk/pypy/doc/config/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/lang/gameboy/tool/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/gameboy/tool/autopath.py (original) +++ pypy/trunk/pypy/lang/gameboy/tool/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/lang/js/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/js/autopath.py (original) +++ pypy/trunk/pypy/lang/js/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/lang/prolog/interpreter/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/prolog/interpreter/autopath.py (original) +++ pypy/trunk/pypy/lang/prolog/interpreter/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/lang/scheme/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/scheme/autopath.py (original) +++ pypy/trunk/pypy/lang/scheme/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/lang/smalltalk/tool/autopath.py ============================================================================== --- pypy/trunk/pypy/lang/smalltalk/tool/autopath.py (original) +++ pypy/trunk/pypy/lang/smalltalk/tool/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/lib/test2/autopath.py ============================================================================== --- pypy/trunk/pypy/lib/test2/autopath.py (original) +++ pypy/trunk/pypy/lib/test2/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/module/__builtin__/test/autopath.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/test/autopath.py (original) +++ pypy/trunk/pypy/module/__builtin__/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/module/_codecs/test/autopath.py ============================================================================== --- pypy/trunk/pypy/module/_codecs/test/autopath.py (original) +++ pypy/trunk/pypy/module/_codecs/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/module/_sre/test/autopath.py ============================================================================== --- pypy/trunk/pypy/module/_sre/test/autopath.py (original) +++ pypy/trunk/pypy/module/_sre/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/module/sys/test/autopath.py ============================================================================== --- pypy/trunk/pypy/module/sys/test/autopath.py (original) +++ pypy/trunk/pypy/module/sys/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/rlib/parsing/test/autopath.py ============================================================================== --- pypy/trunk/pypy/rlib/parsing/test/autopath.py (original) +++ pypy/trunk/pypy/rlib/parsing/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/rlib/rsdl/test/autopath.py ============================================================================== --- pypy/trunk/pypy/rlib/rsdl/test/autopath.py (original) +++ pypy/trunk/pypy/rlib/rsdl/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/rpython/microbench/autopath.py ============================================================================== --- pypy/trunk/pypy/rpython/microbench/autopath.py (original) +++ pypy/trunk/pypy/rpython/microbench/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/tool/algo/test/autopath.py ============================================================================== --- pypy/trunk/pypy/tool/algo/test/autopath.py (original) +++ pypy/trunk/pypy/tool/algo/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/tool/autopath.py ============================================================================== --- pypy/trunk/pypy/tool/autopath.py (original) +++ pypy/trunk/pypy/tool/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/tool/pytest/autopath.py ============================================================================== --- pypy/trunk/pypy/tool/pytest/autopath.py (original) +++ pypy/trunk/pypy/tool/pytest/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/tool/test/autopath.py ============================================================================== --- pypy/trunk/pypy/tool/test/autopath.py (original) +++ pypy/trunk/pypy/tool/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/autopath.py (original) +++ pypy/trunk/pypy/translator/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/benchmark/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/autopath.py (original) +++ pypy/trunk/pypy/translator/benchmark/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/c/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/c/autopath.py (original) +++ pypy/trunk/pypy/translator/c/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/c/test/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/autopath.py (original) +++ pypy/trunk/pypy/translator/c/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/cli/test/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/cli/test/autopath.py (original) +++ pypy/trunk/pypy/translator/cli/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/goal/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/goal/autopath.py (original) +++ pypy/trunk/pypy/translator/goal/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/goal/test2/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/goal/test2/autopath.py (original) +++ pypy/trunk/pypy/translator/goal/test2/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/js/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/js/autopath.py (original) +++ pypy/trunk/pypy/translator/js/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/js/examples/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/js/examples/autopath.py (original) +++ pypy/trunk/pypy/translator/js/examples/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/js/examples/bnb/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/js/examples/bnb/autopath.py (original) +++ pypy/trunk/pypy/translator/js/examples/bnb/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/microbench/pybench/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/microbench/pybench/autopath.py (original) +++ pypy/trunk/pypy/translator/microbench/pybench/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/sandbox/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/autopath.py (original) +++ pypy/trunk/pypy/translator/sandbox/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/sandbox/test/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/test/autopath.py (original) +++ pypy/trunk/pypy/translator/sandbox/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/test/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/test/autopath.py (original) +++ pypy/trunk/pypy/translator/test/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) Modified: pypy/trunk/pypy/translator/tool/autopath.py ============================================================================== --- pypy/trunk/pypy/translator/tool/autopath.py (original) +++ pypy/trunk/pypy/translator/tool/autopath.py Fri Oct 24 17:19:47 2008 @@ -21,8 +21,6 @@ """ -import py - def __dirinfo(part): """ return (partdir, this_dir) and insert parent of partdir into sys.path. If the parent directories don't have the part @@ -129,6 +127,7 @@ # set guaranteed attributes pypydir, this_dir = __dirinfo('pypy') +import py libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) From fijal at codespeak.net Fri Oct 24 17:39:46 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 17:39:46 +0200 (CEST) Subject: [pypy-svn] r59380 - pypy/trunk/pypy/module/_rawffi/test Message-ID: <20081024153946.CB42016A2E3@codespeak.net> Author: fijal Date: Fri Oct 24 17:39:44 2008 New Revision: 59380 Modified: pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py Log: Change imports here Modified: pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py ============================================================================== --- pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py (original) +++ pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py Fri Oct 24 17:39:44 2008 @@ -1,8 +1,8 @@ from pypy.conftest import gettestobjspace -from pypy.translator.tool.cbuild import compile_c_module, \ - ExternalCompilationInfo +from pypy.translator.platform import platform +from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.module._rawffi.interp_rawffi import TYPEMAP from pypy.module._rawffi.tracker import Tracker from pypy.translator.platform import platform From fijal at codespeak.net Fri Oct 24 17:46:58 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 17:46:58 +0200 (CEST) Subject: [pypy-svn] r59381 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081024154658.1C01A16A2DC@codespeak.net> Author: fijal Date: Fri Oct 24 17:46:57 2008 New Revision: 59381 Removed: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: In this shape, test_descr makes no sense whatsoever. Look deeper how this should look like From fijal at codespeak.net Fri Oct 24 17:49:44 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 24 Oct 2008 17:49:44 +0200 (CEST) Subject: [pypy-svn] r59382 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081024154944.DCC5416A2BD@codespeak.net> Author: fijal Date: Fri Oct 24 17:49:44 2008 New Revision: 59382 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py Log: fix typo Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py Fri Oct 24 17:49:44 2008 @@ -6,7 +6,7 @@ import warnings import pickle, cPickle -from test.test_support import TESTFN, unlink, run_unittest, check_impl_details +from test.test_support import TESTFN, unlink, run_unittest, check_impl_detail # XXX This is not really enough, each *operation* should be tested! @@ -257,7 +257,7 @@ 'object' : u'\u3042', 'reason' : 'ouch', 'start' : 0, 'end' : 1}), ] - if check_impl_details: + if check_impl_detail: exceptionList.append( (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 'textStr', 'print_file_and_lineStr'), From arigo at codespeak.net Fri Oct 24 18:57:03 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 24 Oct 2008 18:57:03 +0200 (CEST) Subject: [pypy-svn] r59384 - pypy/trunk/pypy/translator/platform Message-ID: <20081024165703.8865816A175@codespeak.net> Author: arigo Date: Fri Oct 24 18:57:02 2008 New Revision: 59384 Modified: pypy/trunk/pypy/translator/platform/__init__.py Log: Don't create executables with a trailing dot if exe_ext == ''. Modified: pypy/trunk/pypy/translator/platform/__init__.py ============================================================================== --- pypy/trunk/pypy/translator/platform/__init__.py (original) +++ pypy/trunk/pypy/translator/platform/__init__.py Fri Oct 24 18:57:02 2008 @@ -128,7 +128,8 @@ exe_name = py.path.local(os.path.join(str(ofiles[0].dirpath()), outputfilename)) if standalone: - exe_name += '.' + self.exe_ext + if self.exe_ext: + exe_name += '.' + self.exe_ext else: exe_name += '.' + self.so_ext return self._link(self.cc, ofiles, self._link_args_from_eci(eci), From xoraxax at codespeak.net Sat Oct 25 00:51:58 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 25 Oct 2008 00:51:58 +0200 (CEST) Subject: [pypy-svn] r59389 - pypy/trunk/pypy/doc Message-ID: <20081024225158.3011416A1C7@codespeak.net> Author: xoraxax Date: Sat Oct 25 00:51:56 2008 New Revision: 59389 Modified: pypy/trunk/pypy/doc/maemo.txt Log: Reword installation paragraph. Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Sat Oct 25 00:51:56 2008 @@ -127,12 +127,16 @@ XXX IMO this needs either a) cleaner explanation b) a script that does that XXX [creates correct directory to be copied]. "Together with correct path -XXX sounds a bit vague [fijal] +XXX sounds a bit vague [fijal] -- Yes, a kind of "install" script, +XXX which is, like the inherent problem, completely platform invariant. +XXX -- xoraxax :-) When this step is finished, the ``goal`` directory will contain a binary called -``pypy-c`` which is runnable on the Maemo device. Copy it over to your device -together with ``lib-python`` and the ``pypy/lib`` directory (while preserving -correct paths) and you can start it there. +``pypy-c`` which is runnable on the Maemo device. Copy the working directory +of PyPy over to your device. In the directory tree, you only need the newly built file +``pypy/translator/goal/pypy-c`` together with ``lib-python`` and the ``pypy/lib`` directory. +Other files and directories are not necessary. +Finally, you can start it on your Maemo device. From fijal at codespeak.net Sat Oct 25 12:17:05 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 12:17:05 +0200 (CEST) Subject: [pypy-svn] r59390 - pypy/trunk/pypy/doc Message-ID: <20081025101705.7FED416A20D@codespeak.net> Author: fijal Date: Sat Oct 25 12:17:02 2008 New Revision: 59390 Modified: pypy/trunk/pypy/doc/maemo.txt Log: This package is also needed Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Sat Oct 25 12:17:02 2008 @@ -104,7 +104,7 @@ 1. Install these packages to gain full support for extension modules:: - python2.5-dev libffi4-dev zlib1g-dev libbz2-dev libgc-dev + python2.5-dev libffi4-dev zlib1g-dev libbz2-dev libgc-dev libncurses5-dev This can be done by running ``apt-get update`` and ``apt-get install`` accordingly. The latter is only needed if you decide to use the Boehm From fijal at codespeak.net Sat Oct 25 13:01:00 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 13:01:00 +0200 (CEST) Subject: [pypy-svn] r59391 - pypy/build/bot2/pypybuildbot Message-ID: <20081025110100.599A8169F3D@codespeak.net> Author: fijal Date: Sat Oct 25 13:00:57 2008 New Revision: 59391 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: tests make little sense this way Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Sat Oct 25 13:00:57 2008 @@ -128,10 +128,3 @@ setup_steps(platform, self) self.addStep(Translate(["--platform", "maemo", "-Omem"], [])) - - self.addStep(ShellCmd( - description="lib-python test", - command=["python", "pypy/test_all.py", - "--pypy=pypy/translator/goal/pypy-c", - "--resultlog=cpython.log", "lib-python"], - logfiles={'pytestLog': 'cpython.log'})) From fijal at codespeak.net Sat Oct 25 13:01:32 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 13:01:32 +0200 (CEST) Subject: [pypy-svn] r59392 - pypy/trunk/pypy/lib Message-ID: <20081025110132.C8C00169F40@codespeak.net> Author: fijal Date: Sat Oct 25 13:01:31 2008 New Revision: 59392 Modified: pypy/trunk/pypy/lib/_exceptions.py Log: We should have a message on all exceptions Modified: pypy/trunk/pypy/lib/_exceptions.py ============================================================================== --- pypy/trunk/pypy/lib/_exceptions.py (original) +++ pypy/trunk/pypy/lib/_exceptions.py Sat Oct 25 13:01:31 2008 @@ -363,6 +363,7 @@ raise TypeError('argument 4 must be str, not %s'%type(args[4])) else: raise TypeError('function takes exactly 5 arguments (%d given)'%argc) + self.message = "" def __str__(self): if self.end == self.start + 1: @@ -440,6 +441,7 @@ raise TypeError('argument 4 must be str, not %s'%type(args[4])) else: raise TypeError('function takes exactly 5 arguments (%d given)'%argc) + self.message = "" def __str__(self): if self.end == self.start + 1: From fijal at codespeak.net Sat Oct 25 13:02:07 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 13:02:07 +0200 (CEST) Subject: [pypy-svn] r59393 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081025110207.B20D3169F40@codespeak.net> Author: fijal Date: Sat Oct 25 13:02:06 2008 New Revision: 59393 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py Log: Consider this one an implementation detail as well Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py Sat Oct 25 13:02:06 2008 @@ -234,13 +234,6 @@ {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None, 'print_file_and_line' : None, 'msg' : 'msgStr', 'filename' : None, 'lineno' : None, 'offset' : None}), - (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', - 'textStr')), - {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr', - 'args' : ('msgStr', ('filenameStr', 'linenoStr', - 'offsetStr', 'textStr')), - 'print_file_and_line' : None, 'msg' : 'msgStr', - 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}), (UnicodeError, (), {'message' : '', 'args' : (),}), (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'), {'message' : '', 'args' : ('ascii', u'a', 0, 1, @@ -267,6 +260,13 @@ 'print_file_and_line' : None, 'msg' : 'msgStr', 'filename' : None, 'lineno' : None, 'offset' : None}) ) + exceptionList.append(SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', + 'textStr')), + {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr', + 'args' : ('msgStr', ('filenameStr', 'linenoStr', + 'offsetStr', 'textStr')), + 'print_file_and_line' : None, 'msg' : 'msgStr', + 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}) try: exceptionList.append( From fijal at codespeak.net Sat Oct 25 13:29:45 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 13:29:45 +0200 (CEST) Subject: [pypy-svn] r59394 - pypy/trunk/pypy/lib Message-ID: <20081025112945.5899316A240@codespeak.net> Author: fijal Date: Sat Oct 25 13:29:42 2008 New Revision: 59394 Modified: pypy/trunk/pypy/lib/binascii.py Log: Don't try to be smart and reuse algorithm from cpython. Passes test (feel free to revert if you prefer fixing bug in previous alg instead) Modified: pypy/trunk/pypy/lib/binascii.py ============================================================================== --- pypy/trunk/pypy/lib/binascii.py (original) +++ pypy/trunk/pypy/lib/binascii.py Sat Oct 25 13:29:42 2008 @@ -228,28 +228,37 @@ return ''.join(result) + snippet + '\n' def a2b_qp(s, header=False): - parts = s.rstrip('\t ') - if header: - parts = ' '.join(parts.split('_')) - parts = parts.split('=') - # Change the parts in-place - for index, part in enumerate(parts[1:]): - if len(part) and part[0] == '\n': - parts[index + 1] = part[1:] - continue - if len(part) > 1 and part[0] == '\r' and part[1] == '\n': - parts[index + 1] = part[2:] - continue - if len(part) > 1 and part[0] in hex_numbers and part[1] in hex_numbers: - parts[index + 1] = chr(strhex_to_int(part[0:2])) + part[2:] - if parts[index + 1] == '_' and header: - parts[index + 1] = ' ' - elif index == len(parts) - 2 and len(part) < 2: - parts[index + 1] = '' + inp = 0 + odata = [] + while inp < len(s): + if s[inp] == '=': + inp += 1 + if inp >= len(s): + break + # Soft line breaks + if (s[inp] == '\n') or (s[inp] == '\r'): + if s[inp] != '\n': + while inp < len(s) and s[inp] != '\n': + inp += 1 + if inp < len(s): + inp += 1 + elif s[inp] == '=': + # broken case from broken python qp + odata.append('=') + inp += 1 + elif s[inp] in hex_numbers and s[inp + 1] in hex_numbers: + ch = chr(int(s[inp:inp+2], 16)) + inp += 2 + odata.append(ch) + else: + odata.append('=') + elif header and s[inp] == '_': + odata.append(' ') + inp += 1 else: - parts[index + 1] = '=' + parts[index + 1] - - return ''.join(parts) + odata.append(s[inp]) + inp += 1 + return ''.join(odata) def b2a_qp(s, quotetabs=False, istext=True, header=False): """quotetabs=True means that tab and space characters are always From fijal at codespeak.net Sat Oct 25 13:33:56 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 13:33:56 +0200 (CEST) Subject: [pypy-svn] r59395 - pypy/trunk/pypy/module/zlib Message-ID: <20081025113356.A5073169FFA@codespeak.net> Author: fijal Date: Sat Oct 25 13:33:53 2008 New Revision: 59395 Modified: pypy/trunk/pypy/module/zlib/interp_zlib.py Log: fix test_zlib from cpython Modified: pypy/trunk/pypy/module/zlib/interp_zlib.py ============================================================================== --- pypy/trunk/pypy/module/zlib/interp_zlib.py (original) +++ pypy/trunk/pypy/module/zlib/interp_zlib.py Sat Oct 25 13:33:53 2008 @@ -3,7 +3,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.interpreter.error import OperationError -from pypy.rlib.rarithmetic import intmask +from pypy.rlib.rarithmetic import intmask, r_uint from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib import rzlib @@ -37,7 +37,7 @@ checksum = unsigned_to_signed_32bit(checksum) return space.wrap(checksum) -crc32.unwrap_spec = [ObjSpace, 'bufferstr', int] +crc32.unwrap_spec = [ObjSpace, 'bufferstr', r_uint] def adler32(space, string, start = rzlib.ADLER32_DEFAULT_START): @@ -52,7 +52,7 @@ checksum = unsigned_to_signed_32bit(checksum) return space.wrap(checksum) -adler32.unwrap_spec = [ObjSpace, 'bufferstr', int] +adler32.unwrap_spec = [ObjSpace, 'bufferstr', r_uint] def zlib_error(space, msg): From fijal at codespeak.net Sat Oct 25 13:39:11 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 13:39:11 +0200 (CEST) Subject: [pypy-svn] r59396 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081025113911.0B1E916A009@codespeak.net> Author: fijal Date: Sat Oct 25 13:39:11 2008 New Revision: 59396 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_struct.py Log: we raise more kinds of errors in struct. Whether it's good or not is up to discussion, don't explode by now Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_struct.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_struct.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_struct.py Sat Oct 25 13:39:11 2008 @@ -71,7 +71,7 @@ def deprecated_err(func, *args): try: func(*args) - except (struct.error, TypeError): + except (struct.error, TypeError, ValueError, OverflowError): pass except DeprecationWarning: if not PY_STRUCT_OVERFLOW_MASKING: From fijal at codespeak.net Sat Oct 25 13:45:19 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 13:45:19 +0200 (CEST) Subject: [pypy-svn] r59397 - pypy/trunk/pypy/module/struct Message-ID: <20081025114519.F41FB16A015@codespeak.net> Author: fijal Date: Sat Oct 25 13:45:19 2008 New Revision: 59397 Modified: pypy/trunk/pypy/module/struct/__init__.py pypy/trunk/pypy/module/struct/app_struct.py Log: supply dummy Struct type Modified: pypy/trunk/pypy/module/struct/__init__.py ============================================================================== --- pypy/trunk/pypy/module/struct/__init__.py (original) +++ pypy/trunk/pypy/module/struct/__init__.py Sat Oct 25 13:45:19 2008 @@ -55,4 +55,5 @@ 'error': 'app_struct.error', 'pack_into': 'app_struct.pack_into', 'unpack_from': 'app_struct.unpack_from', + 'Struct': 'app_struct.Struct', } Modified: pypy/trunk/pypy/module/struct/app_struct.py ============================================================================== --- pypy/trunk/pypy/module/struct/app_struct.py (original) +++ pypy/trunk/pypy/module/struct/app_struct.py Sat Oct 25 13:45:19 2008 @@ -21,3 +21,21 @@ raise error("unpack_from requires a buffer of at least %d bytes" % (size,)) return struct.unpack(fmt, data) + +# XXX inefficient +class Struct(object): + def __init__(self, format): + self.format = format + self.size = struct.calcsize(format) + + def pack(self, *args): + return struct.pack(self.format, *args) + + def unpack(self, s): + return struct.unpack(self.format, s) + + def pack_into(self, buffer, offset, *args): + return pack_info(self.format, buffer, offset, *args) + + def unpack_from(self, buffer, offset=0): + return unpack_from(self.format, buffer, offset) From fijal at codespeak.net Sat Oct 25 13:46:43 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 13:46:43 +0200 (CEST) Subject: [pypy-svn] r59398 - pypy/trunk/pypy/module/struct Message-ID: <20081025114643.1549016A015@codespeak.net> Author: fijal Date: Sat Oct 25 13:46:43 2008 New Revision: 59398 Modified: pypy/trunk/pypy/module/struct/app_struct.py Log: nice typo :) Modified: pypy/trunk/pypy/module/struct/app_struct.py ============================================================================== --- pypy/trunk/pypy/module/struct/app_struct.py (original) +++ pypy/trunk/pypy/module/struct/app_struct.py Sat Oct 25 13:46:43 2008 @@ -35,7 +35,7 @@ return struct.unpack(self.format, s) def pack_into(self, buffer, offset, *args): - return pack_info(self.format, buffer, offset, *args) + return pack_into(self.format, buffer, offset, *args) def unpack_from(self, buffer, offset=0): return unpack_from(self.format, buffer, offset) From fijal at codespeak.net Sat Oct 25 13:55:57 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 13:55:57 +0200 (CEST) Subject: [pypy-svn] r59399 - pypy/trunk/lib-python Message-ID: <20081025115557.4B0B4169FD9@codespeak.net> Author: fijal Date: Sat Oct 25 13:55:56 2008 New Revision: 59399 Modified: pypy/trunk/lib-python/failure_list.txt Log: update Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Sat Oct 25 13:55:56 2008 @@ -1,11 +1,10 @@ test name !=must fix guess at failure cause or difficulty ------------------------------------------------------------------------------------------- -test__locale ! unknown +test__locale ! wrong locale installation on wyvern test_ast import _ast test_bigmem ! one looks like bug, the others like impl details -test_binascii ! looks like a bug test_builtin this is our issue383 -test_cProfile ! unknown (do we still need to fix module/cProfile?) +test_cProfile ! we still need to fix module/cProfile to respect builtin calls test_capi CPython only test_cmd_line ! implement "pypy-c -V" test_code obscure differences in code objects produced by compiler @@ -20,7 +19,7 @@ test_ctypes ! implementation details but also some real crashes test_datetime ! the two test_negative_*() look like real bugs test_decimal missing decimal.ROUND_05UP -test_descr ! typo in modified/test_descr? +test_descr ! needs deciding what is impl details and what's not test_descrtut implementation detail only test_dis probably not worth the pain of whacking at the compiler test_distutils this is our issue367 @@ -31,7 +30,6 @@ test_email_renamed ! same as test_email test_enumerate same as test_iterlen test_exception_variations ! uh? -test_exceptions ! typo in modified/test_exceptions test_file some more exceptions should be raised test_float float.__getformat__() exists mainly only for tests test_fork1 ! why did this fail just once? @@ -82,9 +80,8 @@ test_sort implementation detail test_sqlite ! why no sqlite available? test_startfile what is os.startfile? -test_str ! segfault :-( +test_str ! Overflow problem in string builder test_string ! segfault :-( -test_struct ! struct.pack() range checking sometimes less strict in CPython test_structmembers CPython-only test_subprocess ! missing resource.error. no clue about os.fpathconf(). test_syntax more small hacking here and there in the ast compiler @@ -114,4 +111,4 @@ test_zipfile ! see test_struct test_zipfile64 skipped test test_zipimport many failures. the test itself seems not to run correctly -test_zlib ! easy to fix + From fijal at codespeak.net Sat Oct 25 15:19:52 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 15:19:52 +0200 (CEST) Subject: [pypy-svn] r59400 - in pypy/trunk/pypy: rpython/lltypesystem translator/c/test Message-ID: <20081025131952.222B916A281@codespeak.net> Author: fijal Date: Sat Oct 25 15:19:50 2008 New Revision: 59400 Added: pypy/trunk/pypy/translator/c/test/test_overflow.py (contents, props changed) Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py Log: A test and a check for single overflow point, more to come Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rstr.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rstr.py Sat Oct 25 15:19:50 2008 @@ -17,6 +17,7 @@ from pypy.rpython.rmodel import Repr from pypy.rpython.lltypesystem import llmemory from pypy.tool.sourcetools import func_with_new_name +from pypy.rlib.rarithmetic import ovfcheck # ____________________________________________________________ # @@ -595,7 +596,11 @@ itemslen = 0 i = 0 while i < num_items: - itemslen += len(items[i].chars) + lgt = len(items[i].chars) + try: + itemslen = ovfcheck(itemslen + lgt) + except OverflowError: + raise i += 1 if typeOf(items).TO.OF.TO == STR: malloc = mallocstr Added: pypy/trunk/pypy/translator/c/test/test_overflow.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/translator/c/test/test_overflow.py Sat Oct 25 15:19:50 2008 @@ -0,0 +1,19 @@ + +""" This is a test that should be in rpython directory. The thing is that +on top of llinterp these tests take forever, so they're here. They usually +segfault when run on top of C, hence inheritance from AbstractGCTestClass +""" + +import py +from pypy.translator.c.test.test_boehm import AbstractGCTestClass + +class TestOverflow(AbstractGCTestClass): + def test_overflow(self): + def f(i): + x = "A" * (2 << i) + ''.join([x] * (2 << i)) + + fn = self.getcompiled(f, [int]) + py.test.raises(OverflowError, fn, 16) + # XXX - we cannot grab overflow check inside test, for obscure + # graph related reasons it gets propagated anyway From fijal at codespeak.net Sat Oct 25 15:28:40 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 15:28:40 +0200 (CEST) Subject: [pypy-svn] r59401 - in pypy/trunk/pypy: rpython/lltypesystem translator/c/test Message-ID: <20081025132840.946C716A049@codespeak.net> Author: fijal Date: Sat Oct 25 15:28:40 2008 New Revision: 59401 Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py pypy/trunk/pypy/translator/c/test/test_overflow.py Log: another test and fix Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rstr.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rstr.py Sat Oct 25 15:28:40 2008 @@ -354,10 +354,17 @@ return s.empty() itemslen = 0 i = 0 - while i < num_items: - itemslen += len(items[i].chars) - i += 1 - result = s.malloc(itemslen + s_len * (num_items - 1)) + try: + while i < num_items: + lgt = len(items[i].chars) + itemslen = ovfcheck(itemslen + lgt) + i += 1 + num_items_1 = num_items - 1 + totalmalloc = ovfcheck(s_len * num_items_1) + totalmalloc = ovfcheck(itemslen + totalmalloc) + except OverflowError: + raise + result = s.malloc(totalmalloc) res_index = len(items[0].chars) s.copy_contents(items[0], result, 0, 0, res_index) i = 1 Modified: pypy/trunk/pypy/translator/c/test/test_overflow.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_overflow.py (original) +++ pypy/trunk/pypy/translator/c/test/test_overflow.py Sat Oct 25 15:28:40 2008 @@ -8,7 +8,7 @@ from pypy.translator.c.test.test_boehm import AbstractGCTestClass class TestOverflow(AbstractGCTestClass): - def test_overflow(self): + def test_ll_join_strs(self): def f(i): x = "A" * (2 << i) ''.join([x] * (2 << i)) @@ -17,3 +17,12 @@ py.test.raises(OverflowError, fn, 16) # XXX - we cannot grab overflow check inside test, for obscure # graph related reasons it gets propagated anyway + + def test_ll_join(self): + def f(i): + x = "A" * (2 << i) + 'a'.join([x] * (2 << i)) + + fn = self.getcompiled(f, [int]) + py.test.raises(OverflowError, fn, 16) + From fijal at codespeak.net Sat Oct 25 15:38:05 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 15:38:05 +0200 (CEST) Subject: [pypy-svn] r59402 - pypy/trunk/pypy/objspace/std Message-ID: <20081025133805.26B5016A07C@codespeak.net> Author: fijal Date: Sat Oct 25 15:38:03 2008 New Revision: 59402 Modified: pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/unicodeobject.py Log: Hum. I'm not sure if this is correct level, but handle unicode object overflows this way Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Sat Oct 25 15:38:03 2008 @@ -504,15 +504,11 @@ substrings_w.append(input[start:]) try: - # XXX conservative estimate. If your strings are that close - # to overflowing, bad luck. - ovfcheck(len(substrings_w) * len(by) + len(input)) + return space.wrap(by.join(substrings_w)) except OverflowError: raise OperationError( space.w_OverflowError, - space.wrap("replace string is too long")) - - return space.wrap(by.join(substrings_w)) + space.wrap("replace string is too long")) def _strip(space, w_self, w_chars, left, right): "internal function called by str_xstrip methods" Modified: pypy/trunk/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/unicodeobject.py Sat Oct 25 15:38:03 2008 @@ -801,14 +801,13 @@ parts = _split_into_chars(self, maxsplit) try: - ovfcheck(len(parts) * len(w_new._value) + len(w_self._value)) - except OverflowError: + # XXX for some obscure reasons CPython can raise here OverflowError + # *or* MemoryError, depends + return W_UnicodeObject(w_new._value.join(parts)) + except (MemoryError, OverflowError): raise OperationError( space.w_OverflowError, - space.wrap("replace string is too long")) - - return W_UnicodeObject(w_new._value.join(parts)) - + space.wrap("replace string is too long")) def unicode_encode__Unicode_ANY_ANY(space, w_unistr, w_encoding=None, From fijal at codespeak.net Sat Oct 25 16:39:53 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 16:39:53 +0200 (CEST) Subject: [pypy-svn] r59403 - pypy/trunk/pypy/module/sys Message-ID: <20081025143953.7F65B169FBE@codespeak.net> Author: fijal Date: Sat Oct 25 16:39:50 2008 New Revision: 59403 Modified: pypy/trunk/pypy/module/sys/version.py Log: Adapt more to CPython standard of displaying version Modified: pypy/trunk/pypy/module/sys/version.py ============================================================================== --- pypy/trunk/pypy/module/sys/version.py (original) +++ pypy/trunk/pypy/module/sys/version.py Sat Oct 25 16:39:50 2008 @@ -29,7 +29,7 @@ return space.wrap(CPYTHON_VERSION) def get_version(space): - return space.wrap("%d.%d.%d (pypy %d.%d.%d build %d)" % ( + return space.wrap("Python %d.%d.%d (pypy %d.%d.%d build %d)" % ( CPYTHON_VERSION[0], CPYTHON_VERSION[1], CPYTHON_VERSION[2], From fijal at codespeak.net Sat Oct 25 16:40:29 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 16:40:29 +0200 (CEST) Subject: [pypy-svn] r59404 - pypy/trunk/pypy/translator/goal Message-ID: <20081025144029.60AD6169FBE@codespeak.net> Author: fijal Date: Sat Oct 25 16:40:29 2008 New Revision: 59404 Modified: pypy/trunk/pypy/translator/goal/app_main.py Log: add -V as synonym for --version Modified: pypy/trunk/pypy/translator/goal/app_main.py ============================================================================== --- pypy/trunk/pypy/translator/goal/app_main.py (original) +++ pypy/trunk/pypy/translator/goal/app_main.py Sat Oct 25 16:40:29 2008 @@ -235,7 +235,7 @@ unbuffered = True elif arg == '-O': pass - elif arg == '--version': + elif arg == '--version' or arg == '-V': print sys.version return 0 elif arg == '--info': From fijal at codespeak.net Sat Oct 25 16:55:30 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 16:55:30 +0200 (CEST) Subject: [pypy-svn] r59405 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081025145530.7B29E16A020@codespeak.net> Author: fijal Date: Sat Oct 25 16:55:29 2008 New Revision: 59405 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_struct.py Log: generalize checks Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_struct.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_struct.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_struct.py Sat Oct 25 16:55:29 2008 @@ -597,8 +597,8 @@ # Go beyond boundaries. small_buf = array.array('c', ' '*10) - assertRaises(struct.error, s.pack_into, small_buf, 0, test_string) - assertRaises(struct.error, s.pack_into, small_buf, 2, test_string) + assertRaises((struct.error, ValueError), s.pack_into, small_buf, 0, test_string) + assertRaises((struct.error, ValueError), s.pack_into, small_buf, 2, test_string) def test_pack_into_fn(): test_string = 'Reykjavik rocks, eow!' @@ -618,8 +618,8 @@ # Go beyond boundaries. small_buf = array.array('c', ' '*10) - assertRaises(struct.error, pack_into, small_buf, 0, test_string) - assertRaises(struct.error, pack_into, small_buf, 2, test_string) + assertRaises((struct.error, ValueError), pack_into, small_buf, 0, test_string) + assertRaises((struct.error, ValueError), pack_into, small_buf, 2, test_string) def test_unpack_with_buffer(): # SF bug 1563759: struct.unpack doens't support buffer protocol objects From fijal at codespeak.net Sat Oct 25 16:55:50 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 16:55:50 +0200 (CEST) Subject: [pypy-svn] r59406 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081025145550.CBC2516A023@codespeak.net> Author: fijal Date: Sat Oct 25 16:55:50 2008 New Revision: 59406 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_builtin.py Log: I think this is implementation specific Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_builtin.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_builtin.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_builtin.py Sat Oct 25 16:55:50 2008 @@ -885,7 +885,8 @@ # call intern internally, e.g. PyObject_SetAttr(). s = S("abc") setattr(s, s, s) - self.assertEqual(getattr(s, s), s) + # XXX I think this is too implementation specific + #self.assertEqual(getattr(s, s), s) def test_iter(self): self.assertRaises(TypeError, iter) From fijal at codespeak.net Sat Oct 25 20:21:26 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 20:21:26 +0200 (CEST) Subject: [pypy-svn] r59407 - in pypy/trunk/pypy: objspace/std rpython/lltypesystem translator/c/test Message-ID: <20081025182126.E54AB16A283@codespeak.net> Author: fijal Date: Sat Oct 25 20:21:25 2008 New Revision: 59407 Removed: pypy/trunk/pypy/translator/c/test/test_overflow.py Modified: pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/unicodeobject.py pypy/trunk/pypy/rpython/lltypesystem/rstr.py Log: Revert moving of overflow checking into rpython level, seems to be a bit ill Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Sat Oct 25 20:21:25 2008 @@ -504,11 +504,15 @@ substrings_w.append(input[start:]) try: - return space.wrap(by.join(substrings_w)) + # XXX conservative estimate. If your strings are that close + # to overflowing, bad luck. + ovfcheck(len(substrings_w) * len(by) + len(input)) except OverflowError: raise OperationError( space.w_OverflowError, - space.wrap("replace string is too long")) + space.wrap("replace string is too long")) + + return space.wrap(by.join(substrings_w)) def _strip(space, w_self, w_chars, left, right): "internal function called by str_xstrip methods" Modified: pypy/trunk/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/unicodeobject.py Sat Oct 25 20:21:25 2008 @@ -801,13 +801,14 @@ parts = _split_into_chars(self, maxsplit) try: - # XXX for some obscure reasons CPython can raise here OverflowError - # *or* MemoryError, depends - return W_UnicodeObject(w_new._value.join(parts)) - except (MemoryError, OverflowError): + ovfcheck(len(parts) * len(w_new._value) + len(w_self._value)) + except OverflowError: raise OperationError( space.w_OverflowError, - space.wrap("replace string is too long")) + space.wrap("replace string is too long")) + + return W_UnicodeObject(w_new._value.join(parts)) + def unicode_encode__Unicode_ANY_ANY(space, w_unistr, w_encoding=None, Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rstr.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rstr.py Sat Oct 25 20:21:25 2008 @@ -17,7 +17,6 @@ from pypy.rpython.rmodel import Repr from pypy.rpython.lltypesystem import llmemory from pypy.tool.sourcetools import func_with_new_name -from pypy.rlib.rarithmetic import ovfcheck # ____________________________________________________________ # @@ -354,17 +353,10 @@ return s.empty() itemslen = 0 i = 0 - try: - while i < num_items: - lgt = len(items[i].chars) - itemslen = ovfcheck(itemslen + lgt) - i += 1 - num_items_1 = num_items - 1 - totalmalloc = ovfcheck(s_len * num_items_1) - totalmalloc = ovfcheck(itemslen + totalmalloc) - except OverflowError: - raise - result = s.malloc(totalmalloc) + while i < num_items: + itemslen += len(items[i].chars) + i += 1 + result = s.malloc(itemslen + s_len * (num_items - 1)) res_index = len(items[0].chars) s.copy_contents(items[0], result, 0, 0, res_index) i = 1 @@ -603,11 +595,7 @@ itemslen = 0 i = 0 while i < num_items: - lgt = len(items[i].chars) - try: - itemslen = ovfcheck(itemslen + lgt) - except OverflowError: - raise + itemslen += len(items[i].chars) i += 1 if typeOf(items).TO.OF.TO == STR: malloc = mallocstr From fijal at codespeak.net Sat Oct 25 20:35:09 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 25 Oct 2008 20:35:09 +0200 (CEST) Subject: [pypy-svn] r59409 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081025183509.3DDC616A1C1@codespeak.net> Author: fijal Date: Sat Oct 25 20:35:07 2008 New Revision: 59409 Modified: pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/test/test_stringobject.py pypy/trunk/pypy/objspace/std/unicodeobject.py Log: Try to hack differently... Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Sat Oct 25 20:35:07 2008 @@ -506,7 +506,8 @@ try: # XXX conservative estimate. If your strings are that close # to overflowing, bad luck. - ovfcheck(len(substrings_w) * len(by) + len(input)) + one = ovfcheck(len(substrings_w) * len(by)) + ovfcheck(one + len(input)) except OverflowError: raise OperationError( space.w_OverflowError, Modified: pypy/trunk/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_stringobject.py Sat Oct 25 20:35:07 2008 @@ -744,6 +744,9 @@ iterable = "hello" raises(TypeError, len, iter(iterable)) + def test_overflow_replace(self): + x = "A" * (2**16) + raises(OverflowError, x.replace, '', x) class AppTestPrebuilt(AppTestStringObject): def setup_class(cls): Modified: pypy/trunk/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/unicodeobject.py Sat Oct 25 20:35:07 2008 @@ -801,7 +801,8 @@ parts = _split_into_chars(self, maxsplit) try: - ovfcheck(len(parts) * len(w_new._value) + len(w_self._value)) + one = ovfcheck(len(parts) * len(w_new._value)) + ovfcheck(one + len(w_self._value)) except OverflowError: raise OperationError( space.w_OverflowError, @@ -867,7 +868,8 @@ pad = tabsize - prevsize % tabsize nextpart = parts[i] try: - totalsize = ovfcheck(totalsize + pad + len(nextpart)) + totalsize = ovfcheck(totalsize + pad) + totalsize = ovfcheck(totalsize + len(nextpart)) result.append(u' ' * pad) except (OverflowError, MemoryError): raise OperationError(space.w_OverflowError, space.wrap('new string is too long')) From arigo at codespeak.net Sun Oct 26 17:16:36 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 26 Oct 2008 17:16:36 +0100 (CET) Subject: [pypy-svn] r59422 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081026161636.CD8FE169FC9@codespeak.net> Author: arigo Date: Sun Oct 26 17:16:34 2008 New Revision: 59422 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_builtin.py Log: No this is a real failure Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_builtin.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_builtin.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_builtin.py Sun Oct 26 17:16:34 2008 @@ -885,8 +885,8 @@ # call intern internally, e.g. PyObject_SetAttr(). s = S("abc") setattr(s, s, s) - # XXX I think this is too implementation specific - #self.assertEqual(getattr(s, s), s) + # see pypy issue #383 + self.assertEqual(getattr(s, s), s) def test_iter(self): self.assertRaises(TypeError, iter) From arigo at codespeak.net Sun Oct 26 17:32:52 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 26 Oct 2008 17:32:52 +0100 (CET) Subject: [pypy-svn] r59423 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081026163252.92D9216A022@codespeak.net> Author: arigo Date: Sun Oct 26 17:32:49 2008 New Revision: 59423 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py Log: These are not implementation details. The impl detail is whether the lineno and offset can be strings or should be (as expected) integers. So it is just a badly-written test. Fix it to pass integers. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_exceptions.py Sun Oct 26 17:32:49 2008 @@ -6,7 +6,7 @@ import warnings import pickle, cPickle -from test.test_support import TESTFN, unlink, run_unittest, check_impl_detail +from test.test_support import TESTFN, unlink, run_unittest # XXX This is not really enough, each *operation* should be tested! @@ -202,6 +202,8 @@ def testAttributes(self): # test that exception attributes are happy + lineno = 42 + offset = 27 exceptionList = [ (BaseException, (), {'message' : '', 'args' : ()}), @@ -234,6 +236,20 @@ {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None, 'print_file_and_line' : None, 'msg' : 'msgStr', 'filename' : None, 'lineno' : None, 'offset' : None}), + (SyntaxError, ('msgStr', ('filenameStr', lineno, offset, + 'textStr')), + {'message' : '', 'offset' : offset, 'text' : 'textStr', + 'args' : ('msgStr', ('filenameStr', lineno, + offset, 'textStr')), + 'print_file_and_line' : None, 'msg' : 'msgStr', + 'filename' : 'filenameStr', 'lineno' : lineno}), + (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', + 'textStr', 'print_file_and_lineStr'), + {'message' : '', 'text' : None, + 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', + 'textStr', 'print_file_and_lineStr'), + 'print_file_and_line' : None, 'msg' : 'msgStr', + 'filename' : None, 'lineno' : None, 'offset' : None}), (UnicodeError, (), {'message' : '', 'args' : (),}), (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'), {'message' : '', 'args' : ('ascii', u'a', 0, 1, @@ -250,24 +266,6 @@ 'object' : u'\u3042', 'reason' : 'ouch', 'start' : 0, 'end' : 1}), ] - if check_impl_detail: - exceptionList.append( - (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', - 'textStr', 'print_file_and_lineStr'), - {'message' : '', 'text' : None, - 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', - 'textStr', 'print_file_and_lineStr'), - 'print_file_and_line' : None, 'msg' : 'msgStr', - 'filename' : None, 'lineno' : None, 'offset' : None}) - ) - exceptionList.append(SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', - 'textStr')), - {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr', - 'args' : ('msgStr', ('filenameStr', 'linenoStr', - 'offsetStr', 'textStr')), - 'print_file_and_line' : None, 'msg' : 'msgStr', - 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}) - try: exceptionList.append( (WindowsError, (1, 'strErrorStr', 'filenameStr'), From fijal at codespeak.net Sun Oct 26 17:59:17 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 26 Oct 2008 17:59:17 +0100 (CET) Subject: [pypy-svn] r59425 - pypy/trunk/lib-python Message-ID: <20081026165917.B002A169F8E@codespeak.net> Author: fijal Date: Sun Oct 26 17:59:17 2008 New Revision: 59425 Modified: pypy/trunk/lib-python/failure_list.txt Log: update this list. Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Sun Oct 26 17:59:17 2008 @@ -1,17 +1,20 @@ test name !=must fix guess at failure cause or difficulty ------------------------------------------------------------------------------------------- -test__locale ! wrong locale installation on wyvern +test__locale arigo wrong locale installation on wyvern + install correct locale on wyvern :-) + test_ast import _ast test_bigmem ! one looks like bug, the others like impl details test_builtin this is our issue383 test_cProfile ! we still need to fix module/cProfile to respect builtin calls test_capi CPython only -test_cmd_line ! implement "pypy-c -V" test_code obscure differences in code objects produced by compiler test_codeccallbacks ! unknown test_codecs ! unknown test_coding ! hah. fix buildbot :-/ -test_coercion ! look at test_prefix_binops, the other is probably too obscure +test_coercion arigo look at test_prefix_binops, the other is probably too obscure + problem with prebuilt objects being equal in result list creation + test_commands ! unknown test_compile ! test_leading_newlines: impl detail; the rest: not good test_compiler ! unknown @@ -80,8 +83,8 @@ test_sort implementation detail test_sqlite ! why no sqlite available? test_startfile what is os.startfile? -test_str ! Overflow problem in string builder -test_string ! segfault :-( +test_str arigo probably skip, investigate +test_string ! some failures, look deeper test_structmembers CPython-only test_subprocess ! missing resource.error. no clue about os.fpathconf(). test_syntax more small hacking here and there in the ast compiler @@ -94,7 +97,7 @@ test_trace probably all acceptable differences test_traceback ! don't care about '__members__', but check the other tests test_tuple ! might be fixed now, check again -test_unicode ! segfault :-( +test_unicode ! some failures, look deeper test_unicode_file skipped test test_unicodedata unknown to me (but xorAxAx and fijal have a better clue) test_urllib2_localnet bogus test? From fijal at codespeak.net Sun Oct 26 21:55:47 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 26 Oct 2008 21:55:47 +0100 (CET) Subject: [pypy-svn] r59427 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081026205547.BB8D8169F11@codespeak.net> Author: fijal Date: Sun Oct 26 21:55:45 2008 New Revision: 59427 Modified: pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/test/test_stringobject.py Log: A test and a fix. oddly enough, unicode is already correct. We should share more code between those two Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Sun Oct 26 21:55:45 2008 @@ -585,7 +585,7 @@ d = u_arg - len(u_self) if d>0: - offset = d//2 + offset = d//2 + (d & u_arg & 1) fillchar = fillchar[0] # annotator hint: it's a single character u_centered = offset * fillchar + u_self + (d - offset) * fillchar else: Modified: pypy/trunk/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_stringobject.py Sun Oct 26 21:55:45 2008 @@ -301,7 +301,7 @@ assert 'abc'.center(2) == 'abc' assert 'abc'.center(5, '*') == '*abc*' # Python 2.4 raises(TypeError, 'abc'.center, 4, 'cba') - + assert ' abc'.center(7) == ' abc ' def test_count(self): assert "".count("x") ==0 From fijal at codespeak.net Sun Oct 26 22:19:53 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 26 Oct 2008 22:19:53 +0100 (CET) Subject: [pypy-svn] r59428 - pypy/trunk/pypy/objspace/std Message-ID: <20081026211953.6F4C1169FD9@codespeak.net> Author: fijal Date: Sun Oct 26 22:19:52 2008 New Revision: 59428 Modified: pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/stringtype.py Log: What the hell, implement this optimization Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Sun Oct 26 22:19:52 2008 @@ -253,7 +253,7 @@ maxsplit -= 1 # NB. if it's already < 0, it stays < 0 # the word is value[i:j] - res_w.append(sliced(space, value, i, j)) + res_w.append(sliced(space, value, i, j, w_self)) # continue to look from the character following the space after the word i = j + 1 @@ -274,11 +274,11 @@ next = value.find(by, start) if next < 0: break - res_w.append(sliced(space, value, start, next)) + res_w.append(sliced(space, value, start, next, w_self)) start = next + bylen maxsplit -= 1 # NB. if it's already < 0, it stays < 0 - res_w.append(sliced(space, value, start, len(value))) + res_w.append(sliced(space, value, start, len(value), w_self)) return space.newlist(res_w) def str_rsplit__String_None_ANY(space, w_self, w_none, w_maxsplit=-1): @@ -308,7 +308,7 @@ # the word is value[j+1:i+1] j1 = j + 1 assert j1 >= 0 - res_w.append(sliced(space, value, j1, i+1)) + res_w.append(sliced(space, value, j1, i+1, w_self)) # continue to look from the character before the space before the word i = j - 1 @@ -330,11 +330,11 @@ next = value.rfind(by, 0, end) if next < 0: break - res_w.append(sliced(space, value, next+bylen, end)) + res_w.append(sliced(space, value, next+bylen, end, w_self)) end = next maxsplit -= 1 # NB. if it's already < 0, it stays < 0 - res_w.append(sliced(space, value, 0, end)) + res_w.append(sliced(space, value, 0, end, w_self)) res_w.reverse() return space.newlist(res_w) @@ -429,9 +429,10 @@ if pos == -1: return space.newtuple([w_self, space.wrap(''), space.wrap('')]) else: - return space.newtuple([sliced(space, self, 0, pos), + return space.newtuple([sliced(space, self, 0, pos, w_self), w_sub, - sliced(space, self, pos+len(sub), len(self))]) + sliced(space, self, pos+len(sub), len(self), + w_self)]) def str_rpartition__String_String(space, w_self, w_sub): self = w_self._value @@ -443,9 +444,9 @@ if pos == -1: return space.newtuple([space.wrap(''), space.wrap(''), w_self]) else: - return space.newtuple([sliced(space, self, 0, pos), + return space.newtuple([sliced(space, self, 0, pos, w_self), w_sub, - sliced(space, self, pos+len(sub), len(self))]) + sliced(space, self, pos+len(sub), len(self), w_self)]) def str_index__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): @@ -533,7 +534,7 @@ rpos -= 1 assert rpos >= lpos # annotator hint, don't remove - return sliced(space, u_self, lpos, rpos) + return sliced(space, u_self, lpos, rpos, w_self) def _strip_none(space, w_self, left, right): "internal function called by str_xstrip methods" @@ -552,7 +553,7 @@ rpos -= 1 assert rpos >= lpos # annotator hint, don't remove - return sliced(space, u_self, lpos, rpos) + return sliced(space, u_self, lpos, rpos, w_self) def str_strip__String_String(space, w_self, w_chars): return _strip(space, w_self, w_chars, left=1, right=1) @@ -695,11 +696,11 @@ i += 1 if u_keepends: eol = i - strs_w.append(sliced(space, data, j, eol)) + strs_w.append(sliced(space, data, j, eol, w_self)) j = i if j < selflen: - strs_w.append(sliced(space, data, j, len(data))) + strs_w.append(sliced(space, data, j, len(data), w_self)) return space.newlist(strs_w) @@ -811,7 +812,7 @@ return W_StringObject.EMPTY elif step == 1: assert start >= 0 and stop >= 0 - return sliced(space, s, start, stop) + return sliced(space, s, start, stop, w_str) else: str = "".join([s[start + i*step] for i in range(sl)]) return wrapstr(space, str) @@ -822,7 +823,7 @@ if start == stop: return W_StringObject.EMPTY else: - return sliced(space, s, start, stop) + return sliced(space, s, start, stop, w_str) def mul_string_times(space, w_str, w_times): try: Modified: pypy/trunk/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringtype.py (original) +++ pypy/trunk/pypy/objspace/std/stringtype.py Sun Oct 26 22:19:52 2008 @@ -39,10 +39,12 @@ return W_RopeObject(rope.LiteralStringNode(c)) return W_StringObject(c) -def sliced(space, s, start, stop): +def sliced(space, s, start, stop, orig_obj): assert start >= 0 assert stop >= 0 assert not space.config.objspace.std.withrope + if start == 0 and stop == len(s) and space.is_w(space.type(orig_obj), space.w_str): + return orig_obj if space.config.objspace.std.withstrslice: from pypy.objspace.std.strsliceobject import W_StringSliceObject # XXX heuristic, should be improved! From fijal at codespeak.net Sun Oct 26 22:22:51 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 26 Oct 2008 22:22:51 +0100 (CET) Subject: [pypy-svn] r59429 - pypy/trunk/pypy/config Message-ID: <20081026212251.87B3916A048@codespeak.net> Author: fijal Date: Sun Oct 26 22:22:51 2008 New Revision: 59429 Modified: pypy/trunk/pypy/config/pypyoption.py Log: Suggest strslice and strjoin for -Omem Modified: pypy/trunk/pypy/config/pypyoption.py ============================================================================== --- pypy/trunk/pypy/config/pypyoption.py (original) +++ pypy/trunk/pypy/config/pypyoption.py Sun Oct 26 22:22:51 2008 @@ -367,6 +367,8 @@ config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withprebuiltchar=True) config.objspace.std.suggest(withsharingdict=True) + config.objspace.std.suggest(withstrslice=True) + config.objspace.std.suggest(withstrjoin=True) # xxx other options? ropes maybe? # completely disable geninterp in a level 0 translation From fijal at codespeak.net Sun Oct 26 22:23:54 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 26 Oct 2008 22:23:54 +0100 (CET) Subject: [pypy-svn] r59430 - pypy/trunk/pypy/objspace/std Message-ID: <20081026212354.5484916856F@codespeak.net> Author: fijal Date: Sun Oct 26 22:23:53 2008 New Revision: 59430 Modified: pypy/trunk/pypy/objspace/std/ropeobject.py Log: yet-another-almost-identical-logic Modified: pypy/trunk/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeobject.py Sun Oct 26 22:23:53 2008 @@ -496,7 +496,7 @@ d = arg - length if d>0: - offset = d//2 + offset = d//2 + (d & arg & 1) fillcharnode = rope.LiteralStringNode.PREBUILT[ord(fillchar)] pre = rope.multiply(fillcharnode, offset) post = rope.multiply(fillcharnode, (d - offset)) From xoraxax at codespeak.net Mon Oct 27 00:38:49 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 27 Oct 2008 00:38:49 +0100 (CET) Subject: [pypy-svn] r59434 - pypy/build/benchmem Message-ID: <20081026233849.7E3F3169EB7@codespeak.net> Author: xoraxax Date: Mon Oct 27 00:38:46 2008 New Revision: 59434 Modified: pypy/build/benchmem/report_graphic.py Log: Filter resultset, show a title. Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Mon Oct 27 00:38:46 2008 @@ -4,17 +4,18 @@ import sys, py import smaps, runbench -from pylab import plot, show +from pylab import plot, show, title def main(filename): resultset = runbench.ResultSet() resultset.parse(py.path.local(filename), True) # by default it shows all graphs, a bit boring, but educating ;) - for name, results in resultset.getname2results(): + for name, results in resultset.filter(benchtype="objsizes").getname2results(): for result in results: lgt = len(result.snapshots) x = [float(i)/lgt for i in range(lgt)] y = [snapshot.private for snapshot in result.snapshots] + title(name) plot(x, y) show() From xoraxax at codespeak.net Mon Oct 27 01:25:03 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 27 Oct 2008 01:25:03 +0100 (CET) Subject: [pypy-svn] r59435 - pypy/build/doc Message-ID: <20081027002503.C5DDD169F9E@codespeak.net> Author: xoraxax Date: Mon Oct 27 01:25:01 2008 New Revision: 59435 Modified: pypy/build/doc/benchmark_memory.txt Log: Some thoughts about memory benchmarking. Modified: pypy/build/doc/benchmark_memory.txt ============================================================================== --- pypy/build/doc/benchmark_memory.txt (original) +++ pypy/build/doc/benchmark_memory.txt Mon Oct 27 01:25:01 2008 @@ -16,7 +16,7 @@ running the GC benchmarks - either launched independently, or forked from a single process -* measure the "percieved pauses" for interactive apps +* measure the "perceived pauses" for interactive apps when running on GCs with stop-the-world collection (i.e. all our framework GCs so far). @@ -55,8 +55,23 @@ * Aim for reproducible results, e.g. by combining some of these techniques: - checkpoints (perform measures at known execution points); + Then we would simply dump allocation information + on every n'th malloc and a few times in every garbage + collection run. + We could either do this by dumping internal information + from the garbage collector (not accounting for rawmalloc + properties) or by blocking the process + in the malloc and gc code and advising the checkpointing + process to checkpoint. Note that this does not reflect + all properties of the virtual memory system because + the page tables will likely also change in between these + synchronization points. - high-res sampling (either in the real system or in emulators, e.g. look at valgrind tools). + - valgrind provides a heap profiler called "massif", + but valgrind only runs on x86 or similar. We can + assume that the heap allocation profile is very + similar on different platforms, right? * The "perceived pause" is probably best approximated by the time it takes to perform a single collection. For @@ -64,6 +79,10 @@ collections of various levels; for example, nursery-only collections are very fast, probably too fast to be noticeable in interactive apps. + + In order to gather this information, the framework GCs + need to be able to dump the collection statistics in a + reusable manner. * real APPS: * some sympy computation/test? From fijal at codespeak.net Mon Oct 27 10:20:25 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 27 Oct 2008 10:20:25 +0100 (CET) Subject: [pypy-svn] r59436 - pypy/trunk/pypy/objspace/std Message-ID: <20081027092025.31BF8169FB8@codespeak.net> Author: fijal Date: Mon Oct 27 10:20:23 2008 New Revision: 59436 Modified: pypy/trunk/pypy/objspace/std/strsliceobject.py Log: fix translation, this code is never executed in tests Modified: pypy/trunk/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/strsliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/strsliceobject.py Mon Oct 27 10:20:23 2008 @@ -82,9 +82,10 @@ if pos == -1: return space.newtuple([w_self, space.wrap(''), space.wrap('')]) else: - return space.newtuple([sliced(space, self, w_self.start, pos), + return space.newtuple([sliced(space, self, w_self.start, pos, w_self), w_sub, - sliced(space, self, pos+len(sub), w_self.stop)]) + sliced(space, self, pos+len(sub), w_self.stop, + w_self)]) def str_rpartition__StringSlice_String(space, w_self, w_sub): self = w_self.str @@ -96,9 +97,10 @@ if pos == -1: return space.newtuple([space.wrap(''), space.wrap(''), w_self]) else: - return space.newtuple([sliced(space, self, w_self.start, pos), + return space.newtuple([sliced(space, self, w_self.start, pos, w_self), w_sub, - sliced(space, self, pos+len(sub), w_self.stop)]) + sliced(space, self, pos+len(sub), w_self.stop, + w_self)]) def str_count__StringSlice_String_ANY_ANY(space, w_self, w_arg, w_start, w_end): From afa at codespeak.net Mon Oct 27 10:58:51 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 27 Oct 2008 10:58:51 +0100 (CET) Subject: [pypy-svn] r59437 - pypy/trunk/pypy/rpython Message-ID: <20081027095851.4DF70169ED3@codespeak.net> Author: afa Date: Mon Oct 27 10:58:49 2008 New Revision: 59437 Modified: pypy/trunk/pypy/rpython/extregistry.py Log: Correctly call the super __init__() method. python2.6 does more checks in type.__init__. Modified: pypy/trunk/pypy/rpython/extregistry.py ============================================================================== --- pypy/trunk/pypy/rpython/extregistry.py (original) +++ pypy/trunk/pypy/rpython/extregistry.py Mon Oct 27 10:58:49 2008 @@ -6,8 +6,7 @@ class AutoRegisteringType(type): def __init__(selfcls, name, bases, dict): - super(AutoRegisteringType, selfcls).__init__(selfcls, - name, bases, dict) + super(AutoRegisteringType, selfcls).__init__(name, bases, dict) if '_about_' in dict: selfcls._register_value(dict['_about_']) del selfcls._about_ # avoid keeping a ref From afa at codespeak.net Mon Oct 27 10:59:40 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 27 Oct 2008 10:59:40 +0100 (CET) Subject: [pypy-svn] r59438 - pypy/trunk/pypy/annotation Message-ID: <20081027095940.55940169ED3@codespeak.net> Author: afa Date: Mon Oct 27 10:59:39 2008 New Revision: 59438 Modified: pypy/trunk/pypy/annotation/model.py Log: Another fix for python2.6: object.__new__ warns when parameters are passed. Modified: pypy/trunk/pypy/annotation/model.py ============================================================================== --- pypy/trunk/pypy/annotation/model.py (original) +++ pypy/trunk/pypy/annotation/model.py Mon Oct 27 10:59:39 2008 @@ -113,7 +113,13 @@ # for debugging, record where each instance comes from # this is disabled if DEBUG is set to False def __new__(cls, *args, **kw): - self = super(SomeObject, cls).__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() From fijal at codespeak.net Mon Oct 27 11:06:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 27 Oct 2008 11:06:33 +0100 (CET) Subject: [pypy-svn] r59439 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081027100633.56292169F3A@codespeak.net> Author: fijal Date: Mon Oct 27 11:06:32 2008 New Revision: 59439 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_mutants.py Log: I suppose it's fine to raise RuntimeError, here, please review Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_mutants.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_mutants.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_mutants.py Mon Oct 27 11:06:32 2008 @@ -137,10 +137,15 @@ while dict1 and len(dict1) == len(dict2): if verbose: print ".", - if random.random() < 0.5: - c = cmp(dict1, dict2) - else: - c = dict1 == dict2 + try: + if random.random() < 0.5: + c = cmp(dict1, dict2) + else: + c = dict1 == dict2 + except RuntimeError: + # it's fine to complain when dictionary size changed + # I think + pass if verbose: print @@ -157,7 +162,7 @@ test_one(random.randrange(1, 100)) # See last comment block for clues about good values for n. -test(20) +test(100) ########################################################################## # Another segfault bug, distilled by Michael Hudson from a c.l.py post. From fijal at codespeak.net Mon Oct 27 12:16:43 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 27 Oct 2008 12:16:43 +0100 (CET) Subject: [pypy-svn] r59440 - pypy/trunk/pypy/lib Message-ID: <20081027111643.DBE5D169F9A@codespeak.net> Author: fijal Date: Mon Oct 27 12:16:41 2008 New Revision: 59440 Modified: pypy/trunk/pypy/lib/datetime.py Log: some fixes Modified: pypy/trunk/pypy/lib/datetime.py ============================================================================== --- pypy/trunk/pypy/lib/datetime.py (original) +++ pypy/trunk/pypy/lib/datetime.py Mon Oct 27 12:16:41 2008 @@ -1397,6 +1397,10 @@ converter = _time.localtime else: converter = _time.gmtime + if 1 - (t % 1.0) < 0.000001: + t = float(int(t)) + 1 + if t < 0: + t -= 1 y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) us = int((t % 1.0) * 1000000) ss = min(ss, 59) # clamp out leap seconds if the platform has them @@ -1408,6 +1412,10 @@ def utcfromtimestamp(cls, t): "Construct a UTC datetime from a POSIX timestamp (like time.time())." + if 1 - (t % 1.0) < 0.000001: + t = float(int(t)) + 1 + if t < 0: + t -= 1 y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t) us = int((t % 1.0) * 1000000) ss = min(ss, 59) # clamp out leap seconds if the platform has them From fijal at codespeak.net Mon Oct 27 12:18:34 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 27 Oct 2008 12:18:34 +0100 (CET) Subject: [pypy-svn] r59441 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081027111834.27726169EB1@codespeak.net> Author: fijal Date: Mon Oct 27 12:18:33 2008 New Revision: 59441 Modified: pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/test/test_stringobject.py Log: A bit artificial "error conditions", enforced by cpython's test suite Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Mon Oct 27 12:18:33 2008 @@ -411,11 +411,15 @@ def str_find__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) + if space.int_w(w_start) > len(self): + return space.wrap(-1) res = self.find(sub, start, end) return space.wrap(res) def str_rfind__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) + if space.int_w(w_start) > len(self): + return space.wrap(-1) res = self.rfind(sub, start, end) return space.wrap(res) Modified: pypy/trunk/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_stringobject.py Mon Oct 27 12:18:33 2008 @@ -445,10 +445,13 @@ raises(TypeError, 'abcdefghijklmn'.index, 'abc', -10.0, 30) def test_rfind(self): + assert 'abc'.rfind('', 4) == -1 assert 'abcdefghiabc'.rfind('abc') == 9 assert 'abcdefghiabc'.rfind('') == 12 assert 'abcdefghiabc'.rfind('abcd') == 0 assert 'abcdefghiabc'.rfind('abcz') == -1 + assert 'abc'.rfind('', 0) == 3 + assert 'abc'.rfind('', 3) == 3 def test_rindex(self): from sys import maxint From afa at codespeak.net Mon Oct 27 13:04:35 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 27 Oct 2008 13:04:35 +0100 (CET) Subject: [pypy-svn] r59442 - in pypy/trunk/pypy: interpreter tool translator/backendopt Message-ID: <20081027120435.02054169F27@codespeak.net> Author: afa Date: Mon Oct 27 13:04:34 2008 New Revision: 59442 Modified: pypy/trunk/pypy/interpreter/gateway.py pypy/trunk/pypy/tool/compat.py pypy/trunk/pypy/tool/gcc_cache.py pypy/trunk/pypy/translator/backendopt/stat.py pypy/trunk/pypy/translator/backendopt/support.py Log: Use "from hashlib import md5" when possible. Now "from pypy.tool.compat import md5" returns a function, not a module. This silences a warning when using python 2.6. Modified: pypy/trunk/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/gateway.py (original) +++ pypy/trunk/pypy/interpreter/gateway.py Mon Oct 27 13:04:34 2008 @@ -889,7 +889,7 @@ from pypy.translator.geninterplevel import translate_as_module import marshal - scramble = md5.new(cls.seed) + scramble = md5(cls.seed) scramble.update(marshal.dumps(self.code)) key = scramble.hexdigest() initfunc = cls.known_code.get(key) @@ -952,7 +952,7 @@ except ImportError: GI_VERSION_RENDERED = 0 from pypy.translator.geninterplevel import GI_VERSION - cls.seed = md5.new(str(GI_VERSION)).digest() + cls.seed = md5(str(GI_VERSION)).digest() if GI_VERSION != GI_VERSION_RENDERED or GI_VERSION is None: for pth in p.listdir(): if pth.check(file=1): Modified: pypy/trunk/pypy/tool/compat.py ============================================================================== --- pypy/trunk/pypy/tool/compat.py (original) +++ pypy/trunk/pypy/tool/compat.py Mon Oct 27 13:04:34 2008 @@ -1,6 +1,10 @@ try: - import md5 + # Preferred way since python 2.6 + from hashlib import md5 except ImportError: - # no _md5 module on this platform - from pypy.lib import md5 + try: + from md5 import md5 + except ImportError: + # no _md5 module on this platform + from pypy.lib.md5 import md5 Modified: pypy/trunk/pypy/tool/gcc_cache.py ============================================================================== --- pypy/trunk/pypy/tool/gcc_cache.py (original) +++ pypy/trunk/pypy/tool/gcc_cache.py Mon Oct 27 13:04:34 2008 @@ -11,7 +11,7 @@ cache_dir = cache_dir_root.join(cachename).ensure(dir=1) filecontents = [c_file.read() for c_file in c_files] key = repr((filecontents, eci)) - hash = md5.md5(key).hexdigest() + hash = md5(key).hexdigest() return cache_dir.join(hash) def build_executable_cache(c_files, eci): Modified: pypy/trunk/pypy/translator/backendopt/stat.py ============================================================================== --- pypy/trunk/pypy/translator/backendopt/stat.py (original) +++ pypy/trunk/pypy/translator/backendopt/stat.py Mon Oct 27 13:04:34 2008 @@ -39,7 +39,7 @@ code = graph.func.func_code.co_code except AttributeError: code = "None" - hash = md5.new(code).hexdigest() + hash = md5(code).hexdigest() details.append((hash, graph.name, nblocks, nops)) details.sort() f = open(save_per_graph_details, "w") Modified: pypy/trunk/pypy/translator/backendopt/support.py ============================================================================== --- pypy/trunk/pypy/translator/backendopt/support.py (original) +++ pypy/trunk/pypy/translator/backendopt/support.py Mon Oct 27 13:04:34 2008 @@ -185,7 +185,7 @@ from pypy.tool.compat import md5 graph2digest = {} for graph in translator.graphs: - m = md5.new() + m = md5() for op in graph_operations(graph): m.update(op.opname + str(op.result)) for a in op.args: From afa at codespeak.net Mon Oct 27 13:11:20 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 27 Oct 2008 13:11:20 +0100 (CET) Subject: [pypy-svn] r59443 - pypy/trunk/pypy/rpython/tool Message-ID: <20081027121120.D83E7169F80@codespeak.net> Author: afa Date: Mon Oct 27 13:11:20 2008 New Revision: 59443 Modified: pypy/trunk/pypy/rpython/tool/rfficache.py Log: Add a sanity check in sizeof_c_type, which fails on my machine: It seems that Visual Studio does not recompile if the input files are too similar :-( Modified: pypy/trunk/pypy/rpython/tool/rfficache.py ============================================================================== --- pypy/trunk/pypy/rpython/tool/rfficache.py (original) +++ pypy/trunk/pypy/rpython/tool/rfficache.py Mon Oct 27 13:11:20 2008 @@ -34,8 +34,12 @@ return build_executable_cache([c_file], eci) def sizeof_c_type(c_typename, **kwds): - question = 'printf("%%d", sizeof(%s));' % (c_typename,); - return int(ask_gcc(question, **kwds)) + question = 'printf("sizeof %s=%%d", sizeof(%s));' % (c_typename, + c_typename) + answer = ask_gcc(question, **kwds).split('=') + assert answer[0] == "sizeof " + c_typename, "wrong program: " \ + "sizeof %s expected, got %s" % (c_typename, answer[0]) + return int(answer[1]) class Platform: def __init__(self): From arigo at codespeak.net Mon Oct 27 13:21:03 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 27 Oct 2008 13:21:03 +0100 (CET) Subject: [pypy-svn] r59444 - in pypy/trunk/pypy/lib: . app_test Message-ID: <20081027122103.A9D9B169FA5@codespeak.net> Author: arigo Date: Mon Oct 27 13:21:03 2008 New Revision: 59444 Added: pypy/trunk/pypy/lib/app_test/test_resource.py (contents, props changed) Modified: pypy/trunk/pypy/lib/resource.py Log: Test and fixes: use _structseq. Added: pypy/trunk/pypy/lib/app_test/test_resource.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/lib/app_test/test_resource.py Mon Oct 27 13:21:03 2008 @@ -0,0 +1,27 @@ +from pypy.lib import resource + +def test_resource(): + x = resource.getrusage(resource.RUSAGE_SELF) + assert len(x) == 16 + assert x[0] == x[-16] == x.ru_utime + assert x[1] == x[-15] == x.ru_stime + assert x[2] == x[-14] == x.ru_maxrss + assert x[3] == x[-13] == x.ru_ixrss + assert x[4] == x[-12] == x.ru_idrss + assert x[5] == x[-11] == x.ru_isrss + assert x[6] == x[-10] == x.ru_minflt + assert x[7] == x[-9] == x.ru_majflt + assert x[8] == x[-8] == x.ru_nswap + assert x[9] == x[-7] == x.ru_inblock + assert x[10] == x[-6] == x.ru_oublock + assert x[11] == x[-5] == x.ru_msgsnd + assert x[12] == x[-4] == x.ru_msgrcv + assert x[13] == x[-3] == x.ru_nsignals + assert x[14] == x[-2] == x.ru_nvcsw + assert x[15] == x[-1] == x.ru_nivcsw + for i in range(16): + if i < 2: + expected_type = float + else: + expected_type = (int, long) + assert isinstance(x[i], expected_type) Modified: pypy/trunk/pypy/lib/resource.py ============================================================================== --- pypy/trunk/pypy/lib/resource.py (original) +++ pypy/trunk/pypy/lib/resource.py Mon Oct 27 13:21:03 2008 @@ -5,6 +5,7 @@ from ctypes_configure.configure import (configure, ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger, SimpleType) +import _structseq _CONSTANTS = ( 'RLIM_INFINITY', @@ -101,23 +102,24 @@ ) class struct_rusage: - def __init__(self, ru): - self.ru_utime = float(ru.ru_utime) - self.ru_stime = float(ru.ru_stime) - self.ru_maxrss = ru.ru_maxrss - self.ru_ixrss = ru.ru_ixrss - self.ru_idrss = ru.ru_idrss - self.ru_isrss = ru.ru_isrss - self.ru_minflt = ru.ru_minflt - self.ru_majflt = ru.ru_majflt - self.ru_nswap = ru.ru_nswap - self.ru_inblock = ru.ru_inblock - self.ru_oublock = ru.ru_oublock - self.ru_msgsnd = ru.ru_msgsnd - self.ru_msgrcv = ru.ru_msgrcv - self.ru_nsignals = ru.ru_nsignals - self.ru_nvcsw = ru.ru_nvcsw - self.ru_nivcsw = ru.ru_nivcsw + __metaclass__ = _structseq.structseqtype + + ru_utime = _structseq.structseqfield(0) + ru_stime = _structseq.structseqfield(1) + ru_maxrss = _structseq.structseqfield(2) + ru_ixrss = _structseq.structseqfield(3) + ru_idrss = _structseq.structseqfield(4) + ru_isrss = _structseq.structseqfield(5) + ru_minflt = _structseq.structseqfield(6) + ru_majflt = _structseq.structseqfield(7) + ru_nswap = _structseq.structseqfield(8) + ru_inblock = _structseq.structseqfield(9) + ru_oublock = _structseq.structseqfield(10) + ru_msgsnd = _structseq.structseqfield(11) + ru_msgrcv = _structseq.structseqfield(12) + ru_nsignals = _structseq.structseqfield(13) + ru_nvcsw = _structseq.structseqfield(14) + ru_nivcsw = _structseq.structseqfield(15) class rlimit(Structure): _fields_ = ( @@ -133,7 +135,24 @@ if errno == EINVAL: raise ValueError("invalid who parameter") raise ResourceError(errno) - return struct_rusage(ru) + return struct_rusage(( + float(ru.ru_utime), + float(ru.ru_stime), + ru.ru_maxrss, + ru.ru_ixrss, + ru.ru_idrss, + ru.ru_isrss, + ru.ru_minflt, + ru.ru_majflt, + ru.ru_nswap, + ru.ru_inblock, + ru.ru_oublock, + ru.ru_msgsnd, + ru.ru_msgrcv, + ru.ru_nsignals, + ru.ru_nvcsw, + ru.ru_nivcsw, + )) def getrlimit(resource): if not(0 <= resource < RLIM_NLIMITS): From afa at codespeak.net Mon Oct 27 13:27:49 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 27 Oct 2008 13:27:49 +0100 (CET) Subject: [pypy-svn] r59445 - pypy/trunk/pypy/translator/platform Message-ID: <20081027122749.CC986169EF7@codespeak.net> Author: afa Date: Mon Oct 27 13:27:49 2008 New Revision: 59445 Modified: pypy/trunk/pypy/translator/platform/windows.py Log: Don't link incrementally on Windows: otherwise the link is skipped if the source file was regenerated too quickly. The previous assert passes in rfficache.py. Modified: pypy/trunk/pypy/translator/platform/windows.py ============================================================================== --- pypy/trunk/pypy/translator/platform/windows.py (original) +++ pypy/trunk/pypy/translator/platform/windows.py Mon Oct 27 13:27:49 2008 @@ -101,7 +101,7 @@ def _link(self, cc, ofiles, link_args, standalone, exe_name): args = ['/nologo'] + [str(ofile) for ofile in ofiles] + link_args - args += ['/out:%s' % (exe_name,)] + args += ['/out:%s' % (exe_name,), '/incremental:no'] if not standalone: args = self._args_for_shared(args) self._execute_c_compiler(self.link, args, exe_name) From witulski at codespeak.net Mon Oct 27 14:57:45 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Mon, 27 Oct 2008 14:57:45 +0100 (CET) Subject: [pypy-svn] r59446 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081027135745.66ADD16A0B4@codespeak.net> Author: witulski Date: Mon Oct 27 14:57:42 2008 New Revision: 59446 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: Added genraisingop2/genraisingop1 to suppoert overflow versions of add and other operations Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Mon Oct 27 14:57:42 2008 @@ -236,12 +236,13 @@ #_POP_QWREG = make_one_operand_instr_with_alternate_encoding(1,0,0,None,"58",None,None) #_PUSH_QWREG = make_one_operand_instr_with_alternate_encoding(1,0,0,None,"50",None,None) - _SETE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0,4) - _SETG_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0,15) - _SETGE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0,13) - _SETL_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0,12) - _SETLE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0,14) - _SETNE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0,5) + _SETE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 4) + _SETG_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 15) + _SETGE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 13) + _SETL_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 12) + _SETLE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 14) + _SETO_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 0) + _SETNE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 5) _SHL_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xD3", 3, None, 4) _SHR_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xD3", 3, None, 5) @@ -252,7 +253,7 @@ _XOR_QWREG_IMM32 = make_two_operand_instr( 1, 0, 0, None, "\x81", 3, None, 6) _XOR_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x31", 3, None, None) - # TODO(all ops): maybe a problem with more ore less than two arg. + # TODO(all ops): maybe a problem with more or less than two arg. def ADD(self, op1, op2): method = getattr(self, "_ADD"+op1.to_string()+op2.to_string()) method(op1, op2) @@ -295,6 +296,7 @@ method = getattr(self, "_INC"+op1.to_string()) method(op1) + # near jump (only the same codeseg.) # 4 length of the immediate # want_jump_to is an 32bit(!) adress def JMP(self,want_jump_to): @@ -304,6 +306,7 @@ self.writeImm32(want_jump_to-self.tell()-4) # 4 length of the immediate + # want_jump_to is an 32bit(!) adress def JNE(self,want_jump_to): self.write("\x0F") self.write("\x85") @@ -347,6 +350,10 @@ method = getattr(self, "_SETL"+op1.to_string()) method(op1) + def SETO(self, op1): + method = getattr(self, "_SETO"+op1.to_string()) + method(op1) + def SETR(self, op1): method = getattr(self, "_SETR"+op1.to_string()) method(op1) @@ -429,22 +436,24 @@ self.write(chr(int(y[0:2],16))) - # Rex-Prefix 4WRXB see AMD vol3 page 45 + # Rex-Prefix 4WRXB see AMD vol3 page 11 def write_rex_byte(self, rexW, rexR, rexX, rexB): byte = (4 << 4) | (rexW << 3) | (rexR << 2) | (rexX << 1) | rexB self.write(chr(byte)) - + + # modRM see AMD vol3 page 17 def write_modRM_byte(self, mod, reg, rm): byte = mod << 6 | (reg << 3) | rm self.write(chr(byte)) + # SIB see AMD vol3 page 17 def write_SIB(self, scale, index, base): byte = scale << 6 | (index << 3) | base self.write(chr(byte)) # calc. the "Two's complement" # and return as pos. hex value. - # This method is used to calc jump displ. + # This method is used to calc. a (neg.) jump displ. def cast_neg_hex32(self,a_int): x = hex(int("FFFFFFFF",16)+1 +a_int) y = x[2:len(x)] Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Mon Oct 27 14:57:42 2008 @@ -13,7 +13,7 @@ # This method calls the assembler to generate code. # It saves the operands in the helpregister gv_z -# and determine the Type of the operands, +# and determine the type of the operands, # to choose the right method in assembler.py def make_two_argument_method(name): def op_int(self, gv_x, gv_y): @@ -66,6 +66,7 @@ self.arg_positions = arg_positions self.stackdepth = stackdepth +# used by emit_moves class MoveEmitter(object): def __init__(self, builder): self.builder = builder @@ -101,7 +102,7 @@ # "r14":None, # "r15":None, } - self._orig_location={} + self._orig_location={}# used to restore the location of a gv self.known_gv = [] # contains the live genvars (used for spilling and allocation) for reg in used_registers: del self.freeregisters[reg.location.reg] @@ -124,19 +125,41 @@ def genop2(self, opname, gv_arg1, gv_arg2): genmethod = getattr(self, 'op_' + opname) return genmethod(gv_arg1, gv_arg2) + + def genraisingop1(self, opname, gv_arg1): + assert opname[len(opname)-4:len(opname)] == "_ovf" + + genmethod = getattr(self, 'op_' + opname[0:len(opname)-4]) + gv_result = genmethod(gv_arg1) + gv_bool = self.allocate_register("rax", gv_result) + self.mc.SETO(IntVar(Register8("al"))) + return gv_result, gv_bool + + # This Method creates an overflow method which + # return the operations result and a flag(BoolVar) + # flag= True if there was an overflow + # it works like genop2 + def genraisingop2(self, opname, gv_arg1, gv_arg2): + assert opname[len(opname)-4:len(opname)] == "_ovf" + + genmethod = getattr(self, 'op_' + opname[0:len(opname)-4]) + gv_result = genmethod(gv_arg1, gv_arg2) + gv_bool = self.allocate_register("rax", gv_result) + self.mc.SETO(IntVar(Register8("al"))) + return gv_result, gv_bool - op_int_add = make_two_argument_method("ADD") # TODO: use inc - op_int_and = make_two_argument_method("AND") - op_int_dec = make_one_argument_method("DEC") # for debuging - op_int_inc = make_one_argument_method("INC") # for debuging - op_int_mul = make_two_argument_method("IMUL") - op_int_neg = make_one_argument_method("NEG") - op_int_not = make_one_argument_method("NOT") # for debuging - op_int_or = make_two_argument_method("OR") - op_int_push = make_one_argument_method("PUSH") # for debuging - op_int_pop = make_one_argument_method("POP") # for debuging - op_int_sub = make_two_argument_method("SUB") # TODO: use DEC - op_int_xor = make_two_argument_method("XOR") + op_int_add = make_two_argument_method("ADD") # TODO: use inc + op_int_and = make_two_argument_method("AND") + op_int_dec = make_one_argument_method("DEC") # for debuging + op_int_inc = make_one_argument_method("INC") # for debuging + op_int_mul = make_two_argument_method("IMUL") + op_int_neg = make_one_argument_method("NEG") + op_int_not = make_one_argument_method("NOT") # for debuging + op_int_or = make_two_argument_method("OR") + op_int_push = make_one_argument_method("PUSH") # for debuging + op_int_pop = make_one_argument_method("POP") # for debuging + op_int_sub = make_two_argument_method("SUB") # TODO: use DEC + op_int_xor = make_two_argument_method("XOR") # must return a genvar def genop_same_as(self, imm): @@ -144,6 +167,7 @@ self.mc.MOV(gv_x, imm) return gv_x + # returns 1 if gv_x is true def op_int_is_true(self, gv_x): [gv_x, gv_y] = self.move_to_registers([gv_x, Immediate32(1)], None, move_imm_too=True) self.mc.CMP(gv_x, gv_y) @@ -182,6 +206,9 @@ self.mc.SHR(gv_x) return gv_x + # called before an assembler operation + # ensures that every genVar is + # inside of a register def move_to_registers(self, registers, dont_alloc = None, move_imm_too = False): if dont_alloc is None: dont_alloc = [] @@ -212,7 +239,7 @@ return gv_z # IDIV RDX:RAX with QWREG - # FIXME: supports only RAX with QWREG + # supports only RAX with QWREG def op_int_mod(self, gv_x, gv_y): gv_z = self.allocate_register("rax") gv_w = self.allocate_register("rdx") @@ -225,6 +252,8 @@ # def op_int_invert(self, gv_x): # return self.mc.NOT(gv_x) + # if a register contains a constant + # it will be marked to be don't spilled def throw_away_if_const(self, registers): for i in range(len(registers)): if registers[i].location.contains_genConst: @@ -313,7 +342,8 @@ from pypy.tool.sourcetools import func_with_new_name def jump(self, gv_condition, args_for_jump_gv): # the targetbuilder must know the registers(live vars) - # of the calling block + # of the calling block and the used stack_pos + # to ensure a correct register allocation targetbuilder = Builder(self.stackdepth, args_for_jump_gv, self.used_stack_pos) self.mc.CMP(gv_condition, Immediate32(value)) self.mc.JNE(targetbuilder.mc.tell()) @@ -324,8 +354,8 @@ jump_if_true = _new_jump('jump_if_true', 0) # moves stackpointer if there are - # gv on the stack which are not - # need anymore + # gv on the stack (which are not + # need anymore) def finish_and_return(self, sigtoken, gv_returnvar): #self.mc.write("\xB8\x0F\x00\x00\x00") self._open() @@ -542,6 +572,8 @@ # TODO: Builder._open() entrypoint = builder.mc.tell() # from http://www.x86-64.org/documentation/abi.pdf + # TODO: also return Stackpositions and let the + # builder know register_list = ["rdi","rsi","rdx","rcx","r8","r9"] # fill the list with the correct registers inputargs_gv = [builder.allocate_register(register_list[i]) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Mon Oct 27 14:57:42 2008 @@ -584,7 +584,7 @@ test_from_random_4_direct = skip test_from_random_5_direct = skip test_genzeroconst = skip - test_ovfcheck_adder_direct = skip + # test_ovfcheck_adder_direct = skip test_ovfcheck1_direct = skip test_ovfcheck2_direct = skip test_cast_direct = skip From witulski at codespeak.net Mon Oct 27 15:15:37 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Mon, 27 Oct 2008 15:15:37 +0100 (CET) Subject: [pypy-svn] r59447 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081027141537.CB8E116A148@codespeak.net> Author: witulski Date: Mon Oct 27 15:15:37 2008 New Revision: 59447 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: Implemented invert Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Mon Oct 27 15:15:37 2008 @@ -249,8 +249,7 @@ self.mc.IDIV(gv_y) return gv_w -# def op_int_invert(self, gv_x): -# return self.mc.NOT(gv_x) + op_int_invert = op_int_not # if a register contains a constant # it will be marked to be don't spilled Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Mon Oct 27 15:15:37 2008 @@ -542,14 +542,14 @@ result = fnptr(42) assert result == 0 - -# def test_invert(self): -# inv_function = make_one_op_instr(self.RGenOp(),"int_invert") -# fnptr = self.cast(inv_function,1) -# result = fnptr(0) -# assert result == 0 -# result = fnptr(1) -# assert result == -1 + # does the same as not + def test_invert(self): + inv_function = make_one_op_instr(self.RGenOp(),"int_invert") + fnptr = self.cast(inv_function,1) + result = fnptr(0) + assert result == -1 + result = fnptr(-43) + assert result == 42 test_switch_many_args_direct = skip @@ -584,7 +584,6 @@ test_from_random_4_direct = skip test_from_random_5_direct = skip test_genzeroconst = skip - # test_ovfcheck_adder_direct = skip test_ovfcheck1_direct = skip test_ovfcheck2_direct = skip test_cast_direct = skip From fijal at codespeak.net Mon Oct 27 16:19:12 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 27 Oct 2008 16:19:12 +0100 (CET) Subject: [pypy-svn] r59448 - pypy/trunk/pypy/module/posix Message-ID: <20081027151912.250DD16A182@codespeak.net> Author: fijal Date: Mon Oct 27 16:19:10 2008 New Revision: 59448 Modified: pypy/trunk/pypy/module/posix/app_posix.py Log: Fix Modified: pypy/trunk/pypy/module/posix/app_posix.py ============================================================================== --- pypy/trunk/pypy/module/posix/app_posix.py (original) +++ pypy/trunk/pypy/module/posix/app_posix.py Mon Oct 27 16:19:10 2008 @@ -82,7 +82,8 @@ pid = self._childpid if pid is not None: self._childpid = None - os.waitpid(pid, 0) + return os.waitpid(pid, 0)[1] + return 0 __del__ = close # as in CPython, __del__ may call os.waitpid() def popen(command, mode='r', bufsize=-1): From afa at codespeak.net Mon Oct 27 16:55:52 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 27 Oct 2008 16:55:52 +0100 (CET) Subject: [pypy-svn] r59449 - pypy/trunk/pypy/rpython/lltypesystem/module Message-ID: <20081027155552.6D09916A139@codespeak.net> Author: afa Date: Mon Oct 27 16:55:51 2008 New Revision: 59449 Modified: pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py Log: Visual Studio uses "the ISO c++ conformant name" instead of the POSIX hypot() function. Modified: pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py Mon Oct 27 16:55:51 2008 @@ -77,7 +77,11 @@ return func_with_new_name(ll_math, 'll_math_' + name) def new_binary_math_function(name): - c_func = rffi.llexternal(name, [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE, + if sys.platform == 'win32' and name in ('hypot',): + cname = '_' + name + else: + cname = name + c_func = rffi.llexternal(cname, [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE, compilation_info=eci, sandboxsafe=True) def ll_math(x, y): From arigo at codespeak.net Mon Oct 27 17:17:31 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 27 Oct 2008 17:17:31 +0100 (CET) Subject: [pypy-svn] r59450 - pypy/trunk/pypy/interpreter/pyparser Message-ID: <20081027161731.4D85116852A@codespeak.net> Author: arigo Date: Mon Oct 27 17:17:30 2008 New Revision: 59450 Modified: pypy/trunk/pypy/interpreter/pyparser/astbuilder.py Log: Minor sanitizing. Modified: pypy/trunk/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/astbuilder.py Mon Oct 27 17:17:30 2008 @@ -1168,16 +1168,16 @@ elif value.startswith("0"): base = 8 if value.endswith('l') or value.endswith('L'): - l = space.builtin.get('long') + l = space.w_long return space.call_function(l, space.wrap(value), space.wrap(base)) if value.endswith('j') or value.endswith('J'): - c = space.builtin.get('complex') + c = space.w_complex return space.call_function(c, space.wrap(value)) try: - i = space.builtin.get('int') + i = space.w_int return space.call_function(i, space.wrap(value), space.wrap(base)) except: - f = space.builtin.get('float') + f = space.w_float return space.call_function(f, space.wrap(value)) def is_basestring_const(self, expr): From arigo at codespeak.net Mon Oct 27 17:17:46 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 27 Oct 2008 17:17:46 +0100 (CET) Subject: [pypy-svn] r59451 - in pypy/trunk/pypy/interpreter/astcompiler: . test Message-ID: <20081027161746.2F518168532@codespeak.net> Author: arigo Date: Mon Oct 27 17:17:45 2008 New Revision: 59451 Modified: pypy/trunk/pypy/interpreter/astcompiler/pyassem.py pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py Log: Test and fix for sharing in co_const. Modified: pypy/trunk/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/pyassem.py Mon Oct 27 17:17:45 2008 @@ -28,8 +28,8 @@ if newlocals: self.flags |= CO_NEWLOCALS - # we need to build an app-level dict here - self.w_consts = space.newdict() + self.w_const2index = space.newdict() # {w_key: wrap(index in consts_w)} + self.consts_w = [] self.names = [] # Free variables found by the symbol table scan, including # variables used only in nested scopes, are included here. @@ -95,27 +95,41 @@ # Instructions with an object argument (LOAD_CONST) def emitop_obj(self, opname, w_obj): - index = self._lookupConst(w_obj, self.w_consts) + index = self._lookupConst(w_obj) self.emitop_int(opname, index) - def _lookupConst(self, w_obj, w_dict): - space = self.space + def _lookupConst(self, w_obj): # insert the docstring first, if necessary - if not space.is_true(w_dict): - w_obj_type = space.type(self.w_docstring) - w_key = space.newtuple([self.w_docstring, w_obj_type]) - space.setitem(w_dict, w_key, space.wrap(0)) - # normal logic follows - w_obj_type = space.type(w_obj) - w_key = space.newtuple([w_obj, w_obj_type]) - try: - w_result = space.getitem(w_dict, w_key) - except OperationError, operr: - if not operr.match(space, space.w_KeyError): - raise - w_result = space.len(w_dict) - space.setitem(w_dict, w_key, w_result) - return space.int_w(w_result) + if len(self.consts_w) == 0: + index = self._lookupConstInternal(self.w_docstring) + assert index == 0 + return self._lookupConstInternal(w_obj) + + def _lookupConstInternal(self, w_obj): + # Some types of object can be shared if equal values appear + # several times in the consts_w. + space = self.space + if (space.is_w(w_obj, space.w_None) or + space.is_w(w_obj, space.w_Ellipsis)): + is_atomic_type = True + else: + w_type = space.type(w_obj) + is_atomic_type = (space.is_w(w_type, space.w_int) or + space.is_w(w_type, space.w_bool) or + space.is_w(w_type, space.w_long) or + space.is_w(w_type, space.w_float) or + space.is_w(w_type, space.w_complex) or + space.is_w(w_type, space.w_str) or + space.is_w(w_type, space.w_unicode)) + if is_atomic_type: + w_index = space.finditem(self.w_const2index, w_obj) + if w_index is not None: + return space.int_w(w_index) + result = len(self.consts_w) + self.consts_w.append(w_obj) + if is_atomic_type: + space.setitem(self.w_const2index, w_obj, space.wrap(result)) + return result # ____________________________________________________________ # Instructions with a name argument @@ -365,17 +379,10 @@ """Return a tuple for the const slot of the code object """ # sanity-check - index = self._lookupConst(self.w_docstring, self.w_consts) + index = self._lookupConst(self.w_docstring) if index != 0: raise InternalCompilerError("setDocstring() called too late") - space = self.space - keys_w = space.unpackiterable(self.w_consts) - l_w = [None] * len(keys_w) - for w_key in keys_w: - index = space.int_w(space.getitem(self.w_consts, w_key)) - w_v = space.viewiterable(w_key)[0] - l_w[index] = w_v - return l_w + return self.consts_w[:] # ____________________________________________________________ Modified: pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py Mon Oct 27 17:17:45 2008 @@ -443,6 +443,10 @@ x = [lineno for addr, lineno in dis.findlinestarts(co)] """, 'x', [3, 4] + def test_type_of_constants(self): + yield self.simple_test, "x=[(1,0), (1,0L)]", 'type(x[1][1])', long + yield self.simple_test, "x=['2?-', '2?-']", 'id(x[0])==id(x[1])', True + def test_pprint(self): # a larger example that showed a bug with jumps # over more than 256 bytes From witulski at codespeak.net Mon Oct 27 17:46:04 2008 From: witulski at codespeak.net (witulski at codespeak.net) Date: Mon, 27 Oct 2008 17:46:04 +0100 (CET) Subject: [pypy-svn] r59452 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test Message-ID: <20081027164604.5E1EB16A1D4@codespeak.net> Author: witulski Date: Mon Oct 27 17:46:01 2008 New Revision: 59452 Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Log: Implemented int_abs (stolen from the other backend ;) ) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py Mon Oct 27 17:46:01 2008 @@ -236,6 +236,7 @@ #_POP_QWREG = make_one_operand_instr_with_alternate_encoding(1,0,0,None,"58",None,None) #_PUSH_QWREG = make_one_operand_instr_with_alternate_encoding(1,0,0,None,"50",None,None) + _SBB_QWREG_QWREG = make_two_operand_instr( 1, None, 0, None, "\x19", 3, None, None) _SETE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 4) _SETG_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 15) _SETGE_8REG = make_one_operand_instr( 0, 0, 0, 0, "\x0F", 3, None, 0, 13) @@ -342,6 +343,10 @@ def RET(self): self.write("\xC3") + def SBB(self, op1, op2): + method = getattr(self, "_SBB"+op1.to_string()+op2.to_string()) + method(op1, op2) + def SETG(self, op1): method = getattr(self, "_SETG"+op1.to_string()) method(op1) Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py Mon Oct 27 17:46:01 2008 @@ -251,6 +251,18 @@ op_int_invert = op_int_not + # stolen from the ia32 backend :) + def op_int_abs(self, gv_x): + gv_y = self.allocate_register() + gv_z = self.allocate_register(None, [gv_y]) + [gv_x] = self.move_to_registers([gv_x], [gv_y, gv_z], move_imm_too=True) + self.mc.MOV(gv_z, gv_x) + self.mc.ADD(gv_x, gv_x) + self.mc.SBB(gv_x, gv_z) + self.mc.SBB(gv_y, gv_y) + self.mc.XOR(gv_x, gv_y) + return gv_x + # if a register contains a constant # it will be marked to be don't spilled def throw_away_if_const(self, registers): Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py Mon Oct 27 17:46:01 2008 @@ -551,6 +551,21 @@ result = fnptr(-43) assert result == 42 + def test_abs(self): + abs_func = make_one_op_instr(self.RGenOp(), "int_abs") + fnptr = self.cast(abs_func, 1) + result = fnptr(1) + assert result == 1 + result = fnptr(123) + assert result == 123 + result = fnptr(-1) + assert result == 1 + result = fnptr(-123) + assert result == 123 + result = fnptr(0) + assert result == 0 + + test_switch_many_args_direct = skip test_directtesthelper_direct = skip @@ -585,7 +600,6 @@ test_from_random_5_direct = skip test_genzeroconst = skip test_ovfcheck1_direct = skip - test_ovfcheck2_direct = skip test_cast_direct = skip test_array_of_ints = skip test_interior_access = skip From antocuni at codespeak.net Mon Oct 27 17:53:10 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 27 Oct 2008 17:53:10 +0100 (CET) Subject: [pypy-svn] r59453 - in pypy/branch/oo-jit/pypy: jit/codegen/cli jit/codegen/cli/test translator/cli/src Message-ID: <20081027165310.8F97416A121@codespeak.net> Author: antocuni Date: Mon Oct 27 17:53:10 2008 New Revision: 59453 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Log: at the end I discovered that the clever-but-complicate approach of InputArgs can't work, because its shape can change when new flexswitch cases are generated. Instead, we simply pass an instance which contains arrays of ints, floats and objects, which can grow of course. It's still in progress, as the code right now doesn't support growing and can only handle ints. Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py Mon Oct 27 17:53:10 2008 @@ -1,156 +1,67 @@ from pypy.translator.cli.dotnet import CLR -from pypy.translator.cli import dotnet +from pypy.translator.cli.dotnet import typeof System = CLR.System -Assembly = System.Reflection.Assembly OpCodes = System.Reflection.Emit.OpCodes - -def new_type_array(types): - array = dotnet.new_array(System.Type, len(types)) - for i in range(len(types)): - array[i] = types[i] - return array +InputArgs = CLR.pypy.runtime.InputArgs class BaseArgsManager: - - def __init__(self): - self.type_counter = {} - self.type_index = {} - self.clitype = None - self._init_types() - - def _init_types(self): - self.clitype_InputArgs = None - self.clitype_Void = None - self.clitype_Pair = None - - def _make_generic_type(self, clitype, paramtypes): - raise NotImplementedError - - def _store_by_index(self, meth, gv_arg, i): - raise NotImplementedError - - def _load_by_index(self, meth, i): - raise NotImplementedError - - def is_open(self): - return self.clitype is None def getCliType(self): - assert not self.is_open() - return self.clitype - - def register_types(self, types): - if not self.is_open(): - return # XXX - - assert self.is_open() - newcounter = {} - for clitype in types: - newcount = newcounter.get(clitype, 0) - newcounter[clitype] = newcount+1 - - for clitype, newcount in newcounter.iteritems(): - oldcount = self.type_counter.get(clitype, 0) - maxcount = max(oldcount, newcount) - self.type_counter[clitype] = maxcount - - def register(self, args_gv): - types = [gv_arg.getCliType() for gv_arg in args_gv] - self.register_types(types) - - def close(self): - assert self.is_open() - fieldtypes = [] - for clitype, count in self.type_counter.iteritems(): - self.type_index[clitype] = len(fieldtypes) - fieldtypes += [clitype] * count - pairtype = self.clitype_Void - - # iterate over reversed(fieldtypes) - i = len(fieldtypes)-1 - while True: - if i < 0: - break - fieldtype = fieldtypes[i] - pairtype = self._make_generic_type(self.clitype_Pair, [fieldtype, pairtype]) - i-=1 - self.clitype = self._make_generic_type(self.clitype_InputArgs, [pairtype]) + return typeof(InputArgs) + def _group_args_by_type(self, args_gv): + clitype2gv = {} + for gv_arg in args_gv: + clitype = self._normalize_type(gv_arg.getCliType()) + clitype2gv.setdefault(clitype, []).append(gv_arg) + return clitype2gv + def copy_to_inputargs(self, meth, args_gv): - "copy args_gv into the appropriate fields of inputargs" - assert not self.is_open() - fieldtypes = [gv_arg.getCliType() for gv_arg in args_gv] - indexes = self._get_indexes(fieldtypes) - assert len(indexes) == len(fieldtypes) - for i in range(len(indexes)): - n = indexes[i] - gv_arg = args_gv[i] - self._store_by_index(meth, gv_arg, n) + clitype2gv = self._group_args_by_type(args_gv) + for clitype, args_gv in clitype2gv.iteritems(): + # XXX: ensure that we have enough items in the array + field, elemtype = self._get_array(clitype) + i = 0 + for gv_arg in args_gv: + self.stelem(meth, i, gv_arg, field, elemtype) + i+=1 def copy_from_inputargs(self, meth, args_gv): - "copy the appropriate fields of inputargs into args_gv" - assert not self.is_open() - fieldtypes = [gv_arg.getCliType() for gv_arg in args_gv] - indexes = self._get_indexes(fieldtypes) - assert len(indexes) == len(fieldtypes) - for i in range(len(indexes)): - n = indexes[i] - gv_arg = args_gv[i] - self._load_by_index(meth, n) - gv_arg.store(meth) - - def _get_indexes(self, fieldtypes): - indexes = [] - next_idx_by_type = {} - for fieldtype in fieldtypes: - startidx = self.type_index[fieldtype] - index = next_idx_by_type.get(fieldtype, startidx) - indexes.append(index) - next_idx_by_type[fieldtype] = index+1 - return indexes + clitype2gv = self._group_args_by_type(args_gv) + for clitype, args_gv in clitype2gv.iteritems(): + field, elemtype = self._get_array(clitype) + i = 0 + for gv_arg in args_gv: + self.ldelem(meth, i, field, elemtype) + gv_arg.store(meth) + i+=1 class ArgsManager(BaseArgsManager): - def _load_pypylib(self): - from pypy.translator.cli.query import pypylib, pypylib2 - assembly = None - for name in [pypylib, pypylib2]: - assembly = Assembly.LoadWithPartialName(name) - if assembly: - break - assert assembly is not None - return assembly - - def _init_types(self): - pypylib = self._load_pypylib() - self.clitype_InputArgs = pypylib.GetType('pypy.runtime.InputArgs`1') - self.clitype_Void = pypylib.GetType('pypy.runtime.Void') - self.clitype_Pair = pypylib.GetType('pypy.runtime.Pair`2') - - def _make_generic_type(self, clitype, paramtypes): - array = new_type_array(paramtypes) - return clitype.MakeGenericType(array) - - def _store_by_index(self, meth, gv_arg, i): - head_info = self._load_nth_head(meth, i) + def stelem(self, meth, i, gv_arg, field, elemtype): + meth.gv_inputargs.load(meth) + meth.il.Emit(OpCodes.Ldfld, field) + meth.il.Emit(OpCodes.Ldc_I4, i) gv_arg.load(meth) - meth.il.Emit(OpCodes.Stfld, head_info) + meth.il.Emit(OpCodes.Stelem, elemtype) - def _load_by_index(self, meth, i): - head_info = self._load_nth_head(meth, i) - meth.il.Emit(OpCodes.Ldfld, head_info) - - def _load_nth_head(self, meth, n): - il = meth.il - fields_info = self.clitype.GetField("fields") + def ldelem(self, meth, i, field, elemtype): meth.gv_inputargs.load(meth) - il.Emit(OpCodes.Ldflda, fields_info) - - lastfield_info = fields_info - for _ in range(n): - fieldtype = lastfield_info.get_FieldType() - lastfield_info = fieldtype.GetField("tail") - il.Emit(OpCodes.Ldflda, lastfield_info) - fieldtype = lastfield_info.get_FieldType() - return fieldtype.GetField("head") + meth.il.Emit(OpCodes.Ldfld, field) + meth.il.Emit(OpCodes.Ldc_I4, i) + meth.il.Emit(OpCodes.Ldelem, elemtype) + + def _normalize_type(self, clitype): + # XXX: generalize! + if clitype == typeof(System.UInt32): + return typeof(System.Int32) + return clitype + + def _get_array(self, clitype): + if clitype == typeof(System.Int32): + field = typeof(InputArgs).GetField('ints') + else: + assert False + ftype = field.get_FieldType() + return field, ftype.GetElementType() Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py Mon Oct 27 17:53:10 2008 @@ -145,11 +145,11 @@ return None def emit(self): + assert self.meth.gv_inputargs is not None # to make the annotator happy il = self.meth.il graphinfo = self.meth.graphinfo graphinfo.args_manager.copy_to_inputargs(self.meth, self.args_gv) block_id = self.target.block_id - #import pdb;pdb.set_trace() il.Emit(OpCodes.Ldc_I4, intmask(block_id)) il.Emit(OpCodes.Ret) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Mon Oct 27 17:53:10 2008 @@ -20,6 +20,7 @@ LowLevelFlexSwitch = CLR.pypy.runtime.LowLevelFlexSwitch FlexSwitchCase = CLR.pypy.runtime.FlexSwitchCase OpCodes = System.Reflection.Emit.OpCodes +InputArgs = CLR.pypy.runtime.InputArgs cVoid = ootype.nullruntimeclass cInt32 = classof(System.Int32) @@ -466,10 +467,6 @@ class GraphInfo: def __init__(self): self.args_manager = ArgsManager() - - # allocate space for the return variable of FlexCaseMethod - # XXX: it should be handled automatically :-( - self.args_manager.register_types([typeof(System.UInt32)]) class MethodGenerator: @@ -522,7 +519,6 @@ block_id = r_uint(self.method_id) << 16 | block_num lbl = Label(self, block_id, args_gv) self.blocks.append(lbl) - self.graphinfo.args_manager.register(args_gv) return lbl def newlocalvar(self, clitype): @@ -646,10 +642,8 @@ def emit_preamble(self): if not self.has_flexswitches: return - # compute the shape of InputArgs - args_manager = self.graphinfo.args_manager - args_manager.close() # InputArgs inputargs = new InputArgs() + args_manager = self.graphinfo.args_manager self.gv_inputargs = self.newlocalvar(args_manager.getCliType()) clitype = self.gv_inputargs.getCliType() ctor = clitype.GetConstructor(new_array(System.Type, 0)) @@ -694,7 +688,6 @@ for gv_arg in linkargs_gv: gv_local = self.newlocalvar(gv_arg.getCliType()) self.linkargs_gv_map[gv_arg] = gv_local - self.graphinfo.args_manager.register(linkargs_gv) def map_genvar(self, gv_var): return self.linkargs_gv_map.get(gv_var, gv_var) @@ -711,15 +704,9 @@ def emit_preamble(self): # the signature of the method is - # int case_0(int jumpto, object args) - - # InputArgs inputargs = (InputArgs)obj + # int case_0(int jumpto, InputArgs args) + self.gv_inputargs = self.inputargs_gv[1] args_manager = self.graphinfo.args_manager - clitype = args_manager.getCliType() - self.gv_inputargs = self.newlocalvar(clitype) - self.inputargs_gv[1].load(self) - self.il.Emit(OpCodes.Castclass, clitype) - self.gv_inputargs.store(self) # 0 is a special value that means "first block of the function", # i.e. don't go through the dispatch block. 0 can never passed as @@ -920,7 +907,7 @@ graph = self.graph name = graph.name + '_case' restype = typeof(System.UInt32) - arglist = [typeof(System.UInt32), class2type(cObject)] + arglist = [typeof(System.UInt32), typeof(InputArgs)] delegatetype = class2type(cFlexSwitchCase) graphinfo = graph.graphinfo meth = FlexCaseMethod(graph.rgenop, name, restype, Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_args_manager.py Mon Oct 27 17:53:10 2008 @@ -3,24 +3,27 @@ class MyArgsManager(BaseArgsManager): - def _init_types(self): - self.clitype_InputArgs = 'InputArgs' - self.clitype_Void = 'Void' - self.clitype_Pair = 'Pair' + def stelem(self, meth, i, gv_arg, field, elemtype): + gv_arg.load(meth) + meth.operations.append(('stelem', field, i)) + + def ldelem(self, meth, i, field, elemtype): + meth.operations.append(('ldelem', field, i)) + + def _normalize_type(self, clitype): + if clitype == 'uint': + return 'int' + return clitype - def _make_generic_type(self, clitype, paramtypes): - return clitype, paramtypes + def _get_array(self, clitype): + return clitype+'s', clitype - def _store_by_index(self, meth, gv_arg, i): - meth.operations.append(('store_arg', gv_arg, i)) - - def _load_by_index(self, meth, i): - meth.operations.append(('load_arg', i)) class FakeMethod: def __init__(self): self.operations = [] + self.gv_inputargs = FakeGenVar('InputArgs') class FakeGenVar: @@ -33,75 +36,46 @@ def store(self, meth): meth.operations.append(('store', self)) + def load(self, meth): + meth.operations.append(('load', self)) -def test_register_types(): - m = MyArgsManager() - assert m.is_open() - m.register_types(['int', 'float', 'int']) - assert m.type_counter['int'] == 2 - assert m.type_counter['float'] == 1 - - m.register_types(['int', 'int', 'int']) - assert m.type_counter['int'] == 3 - assert m.type_counter['float'] == 1 - -def test_close(): - m = MyArgsManager() - m.register_types(['int', 'float', 'int']) - m.close() - assert not m.is_open() - # XXX: this test depend on dictionary order :-/ - assert m.getCliType() == ( - 'InputArgs', [ - ('Pair', [ - 'int', ('Pair', [ - 'int', ('Pair', [ - 'float', 'Void' - ]) - ]) - ]) - ]) - - assert m.type_index['int'] == 0 - assert m.type_index['float'] == 2 - -def test__get_indexes(): - m = MyArgsManager() - m.register_types(['int', 'float', 'int']) - m.close() - indexes = m._get_indexes(['int', 'float', 'int']) - assert indexes == [0, 2, 1] def test_copy_to_inputargs(): meth = FakeMethod() + gv_inputargs = meth.gv_inputargs gv_x = FakeGenVar('int') - gv_y = FakeGenVar('int') - args_gv = [gv_x, gv_y] + gv_y = FakeGenVar('float') + gv_z = FakeGenVar('uint') + args_gv = [gv_x, gv_y, gv_z] m = MyArgsManager() - m.register(args_gv) - m.close() m.copy_to_inputargs(meth, args_gv) assert meth.operations == [ - ('store_arg', gv_x, 0), - ('store_arg', gv_y, 1) + ('load', gv_x), + ('stelem', 'ints', 0), + ('load', gv_z), + ('stelem', 'ints', 1), + ('load', gv_y), + ('stelem', 'floats', 0), ] def test_copy_from_inputargs(): meth = FakeMethod() + gv_inputargs = meth.gv_inputargs gv_x = FakeGenVar('int') - gv_y = FakeGenVar('int') - args_gv = [gv_x, gv_y] + gv_y = FakeGenVar('float') + gv_z = FakeGenVar('uint') + args_gv = [gv_x, gv_y, gv_z] m = MyArgsManager() - m.register(args_gv) - m.close() m.copy_from_inputargs(meth, args_gv) assert meth.operations == [ - ('load_arg', 0), + ('ldelem', 'ints', 0), ('store', gv_x), - ('load_arg', 1), - ('store', gv_y) + ('ldelem', 'ints', 1), + ('store', gv_z), + ('ldelem', 'floats', 0), + ('store', gv_y), ] Modified: pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Mon Oct 27 17:53:10 2008 @@ -105,19 +105,32 @@ namespace pypy.runtime { - public struct Void { - } - - public struct Pair { - public T0 head; - public T1 tail; - } + public class InputArgs { + public int[] ints = new int[32]; + public float[] floats = new float[32]; + public object[] objs = new object[32]; + + public void ensure_ints(int n) + { + if (ints.Length < n) + ints = new int[n]; + } + + public void ensure_floats(int n) + { + if (floats.Length < n) + floats = new float[n]; + } + + public void ensure_objs(int n) + { + if (objs.Length < n) + objs = new object[n]; - public class InputArgs { - public T fields; + } } - public delegate uint FlexSwitchCase(uint block, object args); + public delegate uint FlexSwitchCase(uint block, InputArgs args); public class LowLevelFlexSwitch { @@ -152,7 +165,7 @@ cases = newcases; } - public uint execute(int v, object args) + public uint execute(int v, InputArgs args) { for(int i=0; i Author: xoraxax Date: Mon Oct 27 18:17:49 2008 New Revision: 59454 Modified: pypy/build/doc/benchmark_memory.txt Log: Newest state on memory profiling. Modified: pypy/build/doc/benchmark_memory.txt ============================================================================== --- pypy/build/doc/benchmark_memory.txt (original) +++ pypy/build/doc/benchmark_memory.txt Mon Oct 27 18:17:49 2008 @@ -69,9 +69,21 @@ - high-res sampling (either in the real system or in emulators, e.g. look at valgrind tools). - valgrind provides a heap profiler called "massif", - but valgrind only runs on x86 or similar. We can - assume that the heap allocation profile is very - similar on different platforms, right? + but valgrind only runs on x86 or similar. It gives + useful hints which part of the memory allocator is + claiming the actual memory portion (obmalloc, + semispaces, etc.), but the actual snapshotting feature + is only of limited use because it cannot e.g. differentiate + zeroed pages and pages that are actually used. + - Systemtap is basically a scripting language that + hooks into the kernel. It has been used to benchmark + the execution of certain libraries on systems like + the Maemo platform on ARM. + There has not been any known memory profiling scripts + yet for it; theoretically it is possible, though. + Currently (as of October 2008), Redhat is working on + providing memory profiling scripts, but none of this + work is released yet. * The "perceived pause" is probably best approximated by the time it takes to perform a single collection. For From cami at codespeak.net Mon Oct 27 21:43:07 2008 From: cami at codespeak.net (cami at codespeak.net) Date: Mon, 27 Oct 2008 21:43:07 +0100 (CET) Subject: [pypy-svn] r59456 - pypy/trunk/pypy/translator/goal Message-ID: <20081027204307.1562E16A21E@codespeak.net> Author: cami Date: Mon Oct 27 21:43:05 2008 New Revision: 59456 Modified: pypy/trunk/pypy/translator/goal/targetgbprofiling.py Log: changed the profiling target to print empty results on the forbidden opcodes Modified: pypy/trunk/pypy/translator/goal/targetgbprofiling.py ============================================================================== --- pypy/trunk/pypy/translator/goal/targetgbprofiling.py (original) +++ pypy/trunk/pypy/translator/goal/targetgbprofiling.py Mon Oct 27 21:43:05 2008 @@ -51,6 +51,8 @@ print i, ":", run(op_codes, count) else: print run(op_codes, count) + else: + print -1 def run_each_second_order(count): op_codes = [0xCB]*2 @@ -93,7 +95,6 @@ if i not in forbidden: list.append(0xCB) list.append(i) - return list From afa at codespeak.net Mon Oct 27 23:35:21 2008 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 27 Oct 2008 23:35:21 +0100 (CET) Subject: [pypy-svn] r59457 - pypy/trunk/pypy/tool/algo Message-ID: <20081027223521.E752F16A288@codespeak.net> Author: afa Date: Mon Oct 27 23:35:19 2008 New Revision: 59457 Modified: pypy/trunk/pypy/tool/algo/graphlib.py Log: Remove debug prints Modified: pypy/trunk/pypy/tool/algo/graphlib.py ============================================================================== --- pypy/trunk/pypy/tool/algo/graphlib.py (original) +++ pypy/trunk/pypy/tool/algo/graphlib.py Mon Oct 27 23:35:19 2008 @@ -260,7 +260,7 @@ v_depths = compute_depths(roots, vertices, edges) assert len(v_depths) == len(vertices) # ...so far. We remove # from v_depths the vertices at which we choose to break cycles - print '%d inital roots' % (len(roots,)) + #print '%d inital roots' % (len(roots,)) progress = False for root in roots: if root in roots_finished: @@ -269,7 +269,7 @@ if not cycles: roots_finished.add(root) continue - print 'from root %r: %d cycles' % (root, len(cycles)) + #print 'from root %r: %d cycles' % (root, len(cycles)) # compute the "depth" of each cycles: how far it goes from any root allcycles = [] for cycle in cycles: From arigo at codespeak.net Tue Oct 28 10:26:35 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 10:26:35 +0100 (CET) Subject: [pypy-svn] r59466 - pypy/trunk/lib-python Message-ID: <20081028092635.C613E16A019@codespeak.net> Author: arigo Date: Tue Oct 28 10:26:35 2008 New Revision: 59466 Modified: pypy/trunk/lib-python/failure_list.txt Log: I don't understand this one. Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Tue Oct 28 10:26:35 2008 @@ -1,7 +1,10 @@ test name !=must fix guess at failure cause or difficulty ------------------------------------------------------------------------------------------- -test__locale arigo wrong locale installation on wyvern +test__locale ! wrong locale installation on wyvern install correct locale on wyvern :-) + I don't understand the above comment: + test__locale passes on python2.5 but fails + on pypy-c, so surely there is another problem? test_ast import _ast test_bigmem ! one looks like bug, the others like impl details From arigo at codespeak.net Tue Oct 28 10:27:23 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 10:27:23 +0100 (CET) Subject: [pypy-svn] r59467 - pypy/trunk/lib-python Message-ID: <20081028092723.9ED5D16A032@codespeak.net> Author: arigo Date: Tue Oct 28 10:27:23 2008 New Revision: 59467 Modified: pypy/trunk/lib-python/failure_list.txt Log: Looking at test_descr. Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Tue Oct 28 10:27:23 2008 @@ -25,7 +25,7 @@ test_ctypes ! implementation details but also some real crashes test_datetime ! the two test_negative_*() look like real bugs test_decimal missing decimal.ROUND_05UP -test_descr ! needs deciding what is impl details and what's not +test_descr arigo needs deciding what is impl details and what's not test_descrtut implementation detail only test_dis probably not worth the pain of whacking at the compiler test_distutils this is our issue367 From antocuni at codespeak.net Tue Oct 28 10:38:39 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 28 Oct 2008 10:38:39 +0100 (CET) Subject: [pypy-svn] r59468 - pypy/branch/oo-jit/pypy/jit/codegen/cli Message-ID: <20081028093839.A490816A0C5@codespeak.net> Author: antocuni Date: Tue Oct 28 10:38:35 2008 New Revision: 59468 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Log: rename "JumpFromFlexSwitch" to "NonLocalJump", and rewrite it in a way that should work for all jumps between methods, as it delegates everything to the dispatch block Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py Tue Oct 28 10:38:35 2008 @@ -134,7 +134,7 @@ self.meth.il.Emit(OpCodes.Br, retlabel.il_label) -class JumpFromFlexSwitch(Operation): +class NonLocalJump(Operation): def __init__(self, meth, target, args_gv): self.meth = meth @@ -151,7 +151,8 @@ graphinfo.args_manager.copy_to_inputargs(self.meth, self.args_gv) block_id = self.target.block_id il.Emit(OpCodes.Ldc_I4, intmask(block_id)) - il.Emit(OpCodes.Ret) + il.Emit(OpCodes.Stloc, self.meth.jumpto_var) + il.Emit(OpCodes.Br, self.meth.il_dispatch_block_label) class Call(Operation): Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Tue Oct 28 10:38:35 2008 @@ -694,7 +694,7 @@ def get_op_Return(self, gv_returnvar): target = self.graphinfo.graph_retlabel - return ops.JumpFromFlexSwitch(self, target, [gv_returnvar]) + return ops.NonLocalJump(self, target, [gv_returnvar]) def emit_code(self): MethodGenerator.emit_code(self) @@ -735,6 +735,7 @@ il.Emit(OpCodes.Ldloc, self.jumpto_var) il.Emit(OpCodes.Ret) + class BranchBuilder(GenBuilder): def __init__(self, meth, il_label): @@ -767,8 +768,8 @@ inputargs_gv, label.il_label) else: # jump from a flexswitch to the parent method - op = ops.JumpFromFlexSwitch(self.meth, label, - outputargs_gv) + op = ops.NonLocalJump(self.meth, label, + outputargs_gv) self.appendop(op) self.close() From arigo at codespeak.net Tue Oct 28 14:30:19 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 14:30:19 +0100 (CET) Subject: [pypy-svn] r59474 - pypy/trunk/pypy/interpreter/pyparser/test Message-ID: <20081028133019.4928016A0CB@codespeak.net> Author: arigo Date: Tue Oct 28 14:30:16 2008 New Revision: 59474 Modified: pypy/trunk/pypy/interpreter/pyparser/test/fakes.py Log: Oups. Fix tests. Modified: pypy/trunk/pypy/interpreter/pyparser/test/fakes.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/test/fakes.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/test/fakes.py Tue Oct 28 14:30:16 2008 @@ -4,6 +4,9 @@ w_str = str w_basestring = basestring w_int = int + w_long = long + w_float = float + w_complex = complex def wrap(self, obj): return obj @@ -37,5 +40,3 @@ def call_function(self, func, *args): return func(*args) - - builtin = dict(int=int, long=long, float=float, complex=complex) From fijal at codespeak.net Tue Oct 28 14:39:59 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 14:39:59 +0100 (CET) Subject: [pypy-svn] r59475 - pypy/trunk/pypy/rlib Message-ID: <20081028133959.08F5B16A151@codespeak.net> Author: fijal Date: Tue Oct 28 14:39:58 2008 New Revision: 59475 Modified: pypy/trunk/pypy/rlib/rsocket.py Log: Move this method one level up. This silences last warning during annotation :) Modified: pypy/trunk/pypy/rlib/rsocket.py ============================================================================== --- pypy/trunk/pypy/rlib/rsocket.py (original) +++ pypy/trunk/pypy/rlib/rsocket.py Tue Oct 28 14:39:58 2008 @@ -103,6 +103,11 @@ return rffi.cast(lltype.Ptr(TYPE), self.addr_p) lock._annspecialcase_ = 'specialize:ll' + def lock_in_addr(self): + """ Purely abstract + """ + raise NotImplementedError + def unlock(self): """To call after we're done with the pointer returned by lock(). Note that locking and unlocking costs nothing at run-time. @@ -193,11 +198,6 @@ host, serv = getnameinfo(self, NI_NUMERICHOST | NI_NUMERICSERV) return host - def lock_in_addr(self): - """ Purely abstract - """ - raise NotImplementedError - # ____________________________________________________________ class INETAddress(IPAddress): From arigo at codespeak.net Tue Oct 28 14:55:17 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 14:55:17 +0100 (CET) Subject: [pypy-svn] r59477 - in pypy/trunk/pypy/interpreter/astcompiler: . test Message-ID: <20081028135517.5C5C916A182@codespeak.net> Author: arigo Date: Tue Oct 28 14:55:16 2008 New Revision: 59477 Modified: pypy/trunk/pypy/interpreter/astcompiler/pyassem.py pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py Log: Aaargh. Test and fix. Modified: pypy/trunk/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/pyassem.py Tue Oct 28 14:55:16 2008 @@ -28,7 +28,18 @@ if newlocals: self.flags |= CO_NEWLOCALS - self.w_const2index = space.newdict() # {w_key: wrap(index in consts_w)} + self.atomic_types = [space.type(space.w_None), + space.w_int, + space.w_str, + space.w_unicode, + space.w_bool, + space.w_float, + space.w_long, + space.w_complex, + space.type(space.w_Ellipsis), + ] + self.const2index = [None] * len(self.atomic_types) + # ^^^ each item is a wrapped dict {w_key: wrap(index in consts_w)} self.consts_w = [] self.names = [] # Free variables found by the symbol table scan, including @@ -109,26 +120,22 @@ # Some types of object can be shared if equal values appear # several times in the consts_w. space = self.space - if (space.is_w(w_obj, space.w_None) or - space.is_w(w_obj, space.w_Ellipsis)): - is_atomic_type = True - else: - w_type = space.type(w_obj) - is_atomic_type = (space.is_w(w_type, space.w_int) or - space.is_w(w_type, space.w_bool) or - space.is_w(w_type, space.w_long) or - space.is_w(w_type, space.w_float) or - space.is_w(w_type, space.w_complex) or - space.is_w(w_type, space.w_str) or - space.is_w(w_type, space.w_unicode)) - if is_atomic_type: - w_index = space.finditem(self.w_const2index, w_obj) - if w_index is not None: - return space.int_w(w_index) + w_type = space.type(w_obj) + w_const2index = None + for i in range(len(self.atomic_types)): + if space.is_w(w_type, self.atomic_types[i]): + w_const2index = self.const2index[i] + if w_const2index is None: + w_const2index = self.const2index[i] = space.newdict() + else: + w_index = space.finditem(w_const2index, w_obj) + if w_index is not None: + return space.int_w(w_index) + break result = len(self.consts_w) self.consts_w.append(w_obj) - if is_atomic_type: - space.setitem(self.w_const2index, w_obj, space.wrap(result)) + if w_const2index is not None: + space.setitem(w_const2index, w_obj, space.wrap(result)) return result # ____________________________________________________________ Modified: pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py Tue Oct 28 14:55:16 2008 @@ -444,6 +444,7 @@ """, 'x', [3, 4] def test_type_of_constants(self): + yield self.simple_test, "x=[0, 0L]", 'type(x[1])', long yield self.simple_test, "x=[(1,0), (1,0L)]", 'type(x[1][1])', long yield self.simple_test, "x=['2?-', '2?-']", 'id(x[0])==id(x[1])', True From arigo at codespeak.net Tue Oct 28 14:59:03 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 14:59:03 +0100 (CET) Subject: [pypy-svn] r59478 - pypy/trunk/pypy/rlib Message-ID: <20081028135903.DA1B5169F35@codespeak.net> Author: arigo Date: Tue Oct 28 14:59:03 2008 New Revision: 59478 Modified: pypy/trunk/pypy/rlib/rsocket.py Log: Revert r59475 and use another fix. Modified: pypy/trunk/pypy/rlib/rsocket.py ============================================================================== --- pypy/trunk/pypy/rlib/rsocket.py (original) +++ pypy/trunk/pypy/rlib/rsocket.py Tue Oct 28 14:59:03 2008 @@ -103,11 +103,6 @@ return rffi.cast(lltype.Ptr(TYPE), self.addr_p) lock._annspecialcase_ = 'specialize:ll' - def lock_in_addr(self): - """ Purely abstract - """ - raise NotImplementedError - def unlock(self): """To call after we're done with the pointer returned by lock(). Note that locking and unlocking costs nothing at run-time. @@ -198,6 +193,11 @@ host, serv = getnameinfo(self, NI_NUMERICHOST | NI_NUMERICSERV) return host + def lock_in_addr(self): + """ Purely abstract + """ + raise NotImplementedError + # ____________________________________________________________ class INETAddress(IPAddress): @@ -1114,6 +1114,7 @@ def gethostbyaddr(ip): # XXX use gethostbyaddr_r() if available, and/or use locks if not addr = makeipaddr(ip) + assert isinstance(addr, IPAddress) p, size = addr.lock_in_addr() try: hostent = _c.gethostbyaddr(p, size, addr.family) From fijal at codespeak.net Tue Oct 28 15:07:06 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 15:07:06 +0100 (CET) Subject: [pypy-svn] r59479 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081028140706.54202169F44@codespeak.net> Author: fijal Date: Tue Oct 28 15:07:05 2008 New Revision: 59479 Modified: pypy/trunk/pypy/objspace/std/ropeobject.py pypy/trunk/pypy/objspace/std/slicetype.py pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/test/test_stringobject.py Log: I *think* this is the correct approach. Defer upper bound checks for rpython level strings Modified: pypy/trunk/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeobject.py Tue Oct 28 15:07:05 2008 @@ -333,17 +333,19 @@ else: return W_RopeObject(selfnode) - -def _convert_idx_params(space, w_self, w_sub, w_start, w_end): +def _convert_idx_params(space, w_self, w_sub, w_start, w_end, upper_bound=False): self = w_self._node sub = w_sub._node - start = slicetype.adapt_bound(space, self.length(), w_start) - assert start >= 0 - end = slicetype.adapt_bound(space, self.length(), w_end) - assert end >= 0 + if upper_bound: + start = slicetype.adapt_bound(space, self.length(), w_start) + end = slicetype.adapt_bound(space, self.length(), w_end) + else: + start = slicetype.adapt_lower_bound(space, self.length(), w_start) + end = slicetype.adapt_lower_bound(space, self.length(), w_end) return (self, sub, start, end) +_convert_idx_params._annspecialcase_ = 'specialize:arg(5)' def contains__Rope_Rope(space, w_self, w_sub): self = w_self._node @@ -527,12 +529,14 @@ def str_endswith__Rope_Rope_ANY_ANY(space, w_self, w_suffix, w_start, w_end): (self, suffix, start, end) = _convert_idx_params(space, w_self, - w_suffix, w_start, w_end) + w_suffix, w_start, w_end, + True) return space.newbool(rope.endswith(self, suffix, start, end)) def str_endswith__Rope_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): (self, _, start, end) = _convert_idx_params(space, w_self, - W_RopeObject.EMPTY, w_start, w_end) + W_RopeObject.EMPTY, w_start, + w_end, True) for w_suffix in space.viewiterable(w_suffixes): if space.is_true(space.isinstance(w_suffix, space.w_unicode)): w_u = space.call_function(space.w_unicode, w_self) @@ -546,12 +550,13 @@ def str_startswith__Rope_Rope_ANY_ANY(space, w_self, w_prefix, w_start, w_end): (self, prefix, start, end) = _convert_idx_params(space, w_self, - w_prefix, w_start, w_end) + w_prefix, w_start, w_end, + True) return space.newbool(rope.startswith(self, prefix, start, end)) def str_startswith__Rope_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): (self, _, start, end) = _convert_idx_params(space, w_self, W_RopeObject.EMPTY, - w_start, w_end) + w_start, w_end, True) for w_prefix in space.viewiterable(w_prefixes): if space.is_true(space.isinstance(w_prefix, space.w_unicode)): w_u = space.call_function(space.w_unicode, w_self) Modified: pypy/trunk/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/slicetype.py (original) +++ pypy/trunk/pypy/objspace/std/slicetype.py Tue Oct 28 15:07:05 2008 @@ -24,6 +24,15 @@ space.wrap("slice indices must be integers or " "None or have an __index__ method")) +def adapt_lower_bound(space, size, w_index): + index = _Eval_SliceIndex(space, w_index) + if index < 0: + index = index + size + if index < 0: + index = 0 + assert index >= 0 + return index + def adapt_bound(space, size, w_index): index = _Eval_SliceIndex(space, w_index) if index < 0: @@ -32,6 +41,7 @@ index = 0 if index > size: index = size + assert index >= 0 return index register_all(vars(), globals()) Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Tue Oct 28 15:07:05 2008 @@ -393,16 +393,17 @@ return space.wrap(u_self) -def _convert_idx_params(space, w_self, w_sub, w_start, w_end): +def _convert_idx_params(space, w_self, w_sub, w_start, w_end, upper_bound=False): self = w_self._value sub = w_sub._value - start = slicetype.adapt_bound(space, len(self), w_start) - end = slicetype.adapt_bound(space, len(self), w_end) - - assert start >= 0 - assert end >= 0 - + if upper_bound: + start = slicetype.adapt_bound(space, len(self), w_start) + end = slicetype.adapt_bound(space, len(self), w_end) + else: + start = slicetype.adapt_lower_bound(space, len(self), w_start) + end = slicetype.adapt_lower_bound(space, len(self), w_end) return (self, sub, start, end) +_convert_idx_params.annspecialcase = 'specialize:arg(5)' def contains__String_String(space, w_self, w_sub): self = w_self._value @@ -411,15 +412,11 @@ def str_find__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - if space.int_w(w_start) > len(self): - return space.wrap(-1) res = self.find(sub, start, end) return space.wrap(res) def str_rfind__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - if space.int_w(w_start) > len(self): - return space.wrap(-1) res = self.rfind(sub, start, end) return space.wrap(res) @@ -605,12 +602,14 @@ def str_endswith__String_String_ANY_ANY(space, w_self, w_suffix, w_start, w_end): (u_self, suffix, start, end) = _convert_idx_params(space, w_self, - w_suffix, w_start, w_end) + w_suffix, w_start, + w_end, True) return space.newbool(stringendswith(u_self, suffix, start, end)) def str_endswith__String_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): (u_self, _, start, end) = _convert_idx_params(space, w_self, - space.wrap(''), w_start, w_end) + space.wrap(''), w_start, + w_end, True) for w_suffix in space.viewiterable(w_suffixes): if space.is_true(space.isinstance(w_suffix, space.w_unicode)): w_u = space.call_function(space.w_unicode, w_self) @@ -623,12 +622,13 @@ def str_startswith__String_String_ANY_ANY(space, w_self, w_prefix, w_start, w_end): (u_self, prefix, start, end) = _convert_idx_params(space, w_self, - w_prefix, w_start, w_end) + w_prefix, w_start, + w_end, True) return space.newbool(stringstartswith(u_self, prefix, start, end)) def str_startswith__String_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''), - w_start, w_end) + w_start, w_end, True) for w_prefix in space.viewiterable(w_prefixes): if space.is_true(space.isinstance(w_prefix, space.w_unicode)): w_u = space.call_function(space.w_unicode, w_self) Modified: pypy/trunk/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_stringobject.py Tue Oct 28 15:07:05 2008 @@ -429,6 +429,7 @@ assert 'abcdefghiabc'.find('abc') == 0 assert 'abcdefghiabc'.find('abc', 1) == 9 assert 'abcdefghiabc'.find('def', 4) == -1 + assert 'abcdef'.find('', 13) == -1 def test_index(self): from sys import maxint From fijal at codespeak.net Tue Oct 28 15:11:57 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 15:11:57 +0100 (CET) Subject: [pypy-svn] r59480 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081028141157.E20CC169F44@codespeak.net> Author: fijal Date: Tue Oct 28 15:11:57 2008 New Revision: 59480 Added: pypy/trunk/lib-python/modified-2.5.2/test/string_tests.py - copied, changed from r59439, pypy/trunk/lib-python/2.5.2/test/string_tests.py pypy/trunk/lib-python/modified-2.5.2/test/test_str.py (contents, props changed) Log: Move test_str and string_tests to modified, relax some checks (ie OverflowError vs MemoryError) Copied: pypy/trunk/lib-python/modified-2.5.2/test/string_tests.py (from r59439, pypy/trunk/lib-python/2.5.2/test/string_tests.py) ============================================================================== --- pypy/trunk/lib-python/2.5.2/test/string_tests.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/string_tests.py Tue Oct 28 15:11:57 2008 @@ -252,7 +252,7 @@ self.checkraises(TypeError, 'hello', 'expandtabs', 42, 42) # This test is only valid when sizeof(int) == sizeof(void*) == 4. if sys.maxint < (1 << 32) and struct.calcsize('P') == 4: - self.checkraises(OverflowError, + self.checkraises((MemoryError, OverflowError), '\ta\n\tb', 'expandtabs', sys.maxint) def test_split(self): @@ -936,7 +936,8 @@ self.checkequal('abc', 'abc', '__mul__', 1) self.checkequal('abcabcabc', 'abc', '__mul__', 3) self.checkraises(TypeError, 'abc', '__mul__') - self.checkraises(TypeError, 'abc', '__mul__', '') + if test_support.check_impl_detail: + self.checkraises(TypeError, 'abc', '__mul__', '') # XXX: on a 64-bit system, this doesn't raise an overflow error, # but either raises a MemoryError, or succeeds (if you have 54TiB) #self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000) Added: pypy/trunk/lib-python/modified-2.5.2/test/test_str.py ============================================================================== --- (empty file) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_str.py Tue Oct 28 15:11:57 2008 @@ -0,0 +1,101 @@ + +import unittest +import struct +import sys +from test import test_support, string_tests + + +class StrTest( + string_tests.CommonTest, + string_tests.MixinStrUnicodeUserStringTest, + string_tests.MixinStrUserStringTest, + string_tests.MixinStrUnicodeTest, + ): + + type2test = str + + # We don't need to propagate to str + def fixtype(self, obj): + return obj + + def test_formatting(self): + string_tests.MixinStrUnicodeUserStringTest.test_formatting(self) + self.assertRaises(OverflowError, '%c'.__mod__, 0x1234) + + def test_conversion(self): + # Make sure __str__() behaves properly + class Foo0: + def __unicode__(self): + return u"foo" + + class Foo1: + def __str__(self): + return "foo" + + class Foo2(object): + def __str__(self): + return "foo" + + class Foo3(object): + def __str__(self): + return u"foo" + + class Foo4(unicode): + def __str__(self): + return u"foo" + + class Foo5(str): + def __str__(self): + return u"foo" + + class Foo6(str): + def __str__(self): + return "foos" + + def __unicode__(self): + return u"foou" + + class Foo7(unicode): + def __str__(self): + return "foos" + def __unicode__(self): + return u"foou" + + class Foo8(str): + def __new__(cls, content=""): + return str.__new__(cls, 2*content) + def __str__(self): + return self + + class Foo9(str): + def __str__(self): + return "string" + def __unicode__(self): + return "not unicode" + + self.assert_(str(Foo0()).startswith("<")) # this is different from __unicode__ + self.assertEqual(str(Foo1()), "foo") + self.assertEqual(str(Foo2()), "foo") + self.assertEqual(str(Foo3()), "foo") + self.assertEqual(str(Foo4("bar")), "foo") + self.assertEqual(str(Foo5("bar")), "foo") + self.assertEqual(str(Foo6("bar")), "foos") + self.assertEqual(str(Foo7("bar")), "foos") + self.assertEqual(str(Foo8("foo")), "foofoo") + self.assertEqual(str(Foo9("foo")), "string") + self.assertEqual(unicode(Foo9("foo")), u"not unicode") + + def test_expandtabs_overflows_gracefully(self): + # This test only affects 32-bit platforms because expandtabs can only take + # an int as the max value, not a 64-bit C long. If expandtabs is changed + # to take a 64-bit long, this test should apply to all platforms. + if sys.maxint > (1 << 32) or struct.calcsize('P') != 4: + return + self.assertRaises((OverflowError, MemoryError), 't\tt\t'.expandtabs, sys.maxint) + + +def test_main(): + test_support.run_unittest(StrTest) + +if __name__ == "__main__": + test_main() From fijal at codespeak.net Tue Oct 28 15:13:32 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 15:13:32 +0100 (CET) Subject: [pypy-svn] r59481 - pypy/trunk/lib-python Message-ID: <20081028141332.A7154169F44@codespeak.net> Author: fijal Date: Tue Oct 28 15:13:32 2008 New Revision: 59481 Modified: pypy/trunk/lib-python/failure_list.txt Log: this one passes now Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Tue Oct 28 15:13:32 2008 @@ -7,7 +7,6 @@ on pypy-c, so surely there is another problem? test_ast import _ast -test_bigmem ! one looks like bug, the others like impl details test_builtin this is our issue383 test_cProfile ! we still need to fix module/cProfile to respect builtin calls test_capi CPython only From fijal at codespeak.net Tue Oct 28 15:31:28 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 15:31:28 +0100 (CET) Subject: [pypy-svn] r59482 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081028143128.7146F169F4F@codespeak.net> Author: fijal Date: Tue Oct 28 15:31:25 2008 New Revision: 59482 Modified: pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/test/test_stringobject.py Log: Test and a fix for str.replace(buffer, buffer) Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Tue Oct 28 15:31:25 2008 @@ -11,6 +11,7 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.tupleobject import W_TupleObject from pypy.rlib.rstring import StringBuilder +from pypy.interpreter.buffer import StringBuffer from pypy.objspace.std.stringtype import sliced, joined, wrapstr, wrapchar, \ stringendswith, stringstartswith, joined2 @@ -469,12 +470,7 @@ return space.wrap(res) - -def str_replace__String_String_String_ANY(space, w_self, w_sub, w_by, w_maxsplit=-1): - input = w_self._value - sub = w_sub._value - by = w_by._value - maxsplit = space.int_w(w_maxsplit) +def _string_replace(space, input, sub, by, maxsplit): if maxsplit == 0: return space.wrap(input) @@ -516,6 +512,18 @@ space.wrap("replace string is too long")) return space.wrap(by.join(substrings_w)) + + +def str_replace__String_ANY_ANY_ANY(space, w_self, w_sub, w_by, w_maxsplit): + return _string_replace(space, w_self._value, space.buffer_w(w_sub).value, + space.buffer_w(w_by).value, space.int_w(w_maxsplit)) + +def str_replace__String_String_String_ANY(space, w_self, w_sub, w_by, w_maxsplit=-1): + input = w_self._value + sub = w_sub._value + by = w_by._value + maxsplit = space.int_w(w_maxsplit) + return _string_replace(space, input, sub, by, maxsplit) def _strip(space, w_self, w_chars, left, right): "internal function called by str_xstrip methods" Modified: pypy/trunk/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_stringobject.py Tue Oct 28 15:31:25 2008 @@ -259,6 +259,9 @@ assert '123123'.replace('123', '') == '' assert '123x123'.replace('123', '') == 'x' + def test_replace_buffer(self): + assert 'one'.replace(buffer('o'), buffer('n'), 1) == 'nne' + assert 'one'.replace(buffer('o'), buffer('n')) == 'nne' def test_strip(self): s = " a b " From fijal at codespeak.net Tue Oct 28 15:39:29 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 15:39:29 +0100 (CET) Subject: [pypy-svn] r59484 - pypy/trunk/pypy/objspace/std Message-ID: <20081028143929.5509516A0BF@codespeak.net> Author: fijal Date: Tue Oct 28 15:39:28 2008 New Revision: 59484 Modified: pypy/trunk/pypy/objspace/std/stringobject.py Log: Use official buffer API Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Tue Oct 28 15:39:28 2008 @@ -515,8 +515,9 @@ def str_replace__String_ANY_ANY_ANY(space, w_self, w_sub, w_by, w_maxsplit): - return _string_replace(space, w_self._value, space.buffer_w(w_sub).value, - space.buffer_w(w_by).value, space.int_w(w_maxsplit)) + return _string_replace(space, w_self._value, space.buffer_w(w_sub).as_str(), + space.buffer_w(w_by).as_str(), + space.int_w(w_maxsplit)) def str_replace__String_String_String_ANY(space, w_self, w_sub, w_by, w_maxsplit=-1): input = w_self._value From fijal at codespeak.net Tue Oct 28 15:45:00 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 15:45:00 +0100 (CET) Subject: [pypy-svn] r59485 - pypy/trunk/pypy/interpreter/test Message-ID: <20081028144500.71BB316A0BF@codespeak.net> Author: fijal Date: Tue Oct 28 15:44:59 2008 New Revision: 59485 Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py Log: Showcase our level of 2.5 support Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_compiler.py (original) +++ pypy/trunk/pypy/interpreter/test/test_compiler.py Tue Oct 28 15:44:59 2008 @@ -141,6 +141,19 @@ ex = e.value assert ex.match(self.space, self.space.w_SyntaxError) + def test_try_except_finally(self): + py.test.skip("FAILS!") + s = py.code.Source(""" + def f(): + try: + 1/0 + except ZeroDivisionError: + pass + finally: + return 3 + """) + self.compiler.compile(str(s), '', 'exec', 0) + def test_toplevel_docstring(self): space = self.space code = self.compiler.compile('"spam"; "bar"; x=5', '', 'exec', 0) From arigo at codespeak.net Tue Oct 28 16:51:19 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 16:51:19 +0100 (CET) Subject: [pypy-svn] r59487 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081028155119.07DA616A017@codespeak.net> Author: arigo Date: Tue Oct 28 16:51:17 2008 New Revision: 59487 Added: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py - copied, changed from r59421, pypy/trunk/lib-python/2.5.2/test/test_descr.py Log: Start to fix test_descr from scratch. This time the goal is to make it fully pass on both python2.5 and pypy-c, with possibly a few "impl_detail" checks. Copied: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (from r59421, pypy/trunk/lib-python/2.5.2/test/test_descr.py) ============================================================================== --- pypy/trunk/lib-python/2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Tue Oct 28 16:51:17 2008 @@ -21,7 +21,9 @@ m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - vereq(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + vereq(getattr(m, 'im_func', m), t.__dict__[meth]) vereq(m(a), res) bm = getattr(a, meth) vereq(bm(), res) @@ -39,7 +41,9 @@ m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - vereq(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + vereq(getattr(m, 'im_func', m), t.__dict__[meth]) vereq(m(a, b), res) bm = getattr(a, meth) vereq(bm(b), res) @@ -52,7 +56,9 @@ m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - vereq(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + vereq(getattr(m, 'im_func', m), t.__dict__[meth]) vereq(m(a, b, c), res) bm = getattr(a, meth) vereq(bm(b, c), res) @@ -66,7 +72,9 @@ m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - vereq(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + vereq(getattr(m, 'im_func', m), t.__dict__[meth]) dict['a'] = deepcopy(a) m(dict['a'], b) vereq(dict['a'], res) @@ -84,7 +92,9 @@ m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - vereq(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + vereq(getattr(m, 'im_func', m), t.__dict__[meth]) dict['a'] = deepcopy(a) m(dict['a'], b, c) vereq(dict['a'], res) @@ -102,7 +112,9 @@ while meth not in t.__dict__: t = t.__bases__[0] m = getattr(t, meth) - vereq(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + vereq(getattr(m, 'im_func', m), t.__dict__[meth]) dict['a'] = deepcopy(a) m(dict['a'], b, c, d) vereq(dict['a'], res) From arigo at codespeak.net Tue Oct 28 16:55:49 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 16:55:49 +0100 (CET) Subject: [pypy-svn] r59488 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081028155549.A12FB169F52@codespeak.net> Author: arigo Date: Tue Oct 28 16:55:48 2008 New Revision: 59488 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Two implementation details. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Tue Oct 28 16:55:48 2008 @@ -1,6 +1,7 @@ # Test enhancements related to descriptors and new-style classes from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout +from test.test_support import check_impl_detail from copy import deepcopy import warnings import types @@ -168,7 +169,10 @@ def dicts(): if verbose: print "Testing dict operations..." - testbinop({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__") + testbinop({1:2}, {2:1}, False, "a == b", "__eq__") + testbinop({1:2}, {2:1}, True, "a != b", "__ne__") + if hasattr(dict, '__cmp__'): # PyPy has only rich comparison on dicts + testbinop({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__") testbinop({1:2,3:4}, 1, 1, "b in a", "__contains__") testbinop({1:2,3:4}, 2, 0, "b in a", "__contains__") testbinop({1:2,3:4}, 1, 2, "a[b]", "__getitem__") @@ -376,7 +380,9 @@ # Two essentially featureless objects, just inheriting stuff from # object. - vereq(dir(None), dir(Ellipsis)) + vereq(dir(NotImplemented), dir(Ellipsis)) + if check_impl_detail: # None might differ: it can have __nonzero__ + vereq(dir(None), dir(Ellipsis)) # Nasty test case for proxied objects class Wrapper(object): From antocuni at codespeak.net Tue Oct 28 16:59:16 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 28 Oct 2008 16:59:16 +0100 (CET) Subject: [pypy-svn] r59489 - in pypy/branch/oo-jit/pypy: jit/codegen/cli jit/codegen/test translator/cli/src Message-ID: <20081028155916.8819E169F9A@codespeak.net> Author: antocuni Date: Tue Oct 28 16:59:15 2008 New Revision: 59489 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Log: implement jumping between any two blocks in the graph, even if they are in two different methods. Flexswitch implementation should be complete now :-) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py Tue Oct 28 16:59:15 2008 @@ -302,7 +302,7 @@ graph = self.meth il = graph.il # get MethodInfo for LowLevelFlexSwitch.execute - clitype = self.gv_flexswitch.llflexswitch.GetType() + clitype = self.gv_flexswitch.getCliType() meth_execute = clitype.GetMethod('execute') # setup the correct inputargs Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Tue Oct 28 16:59:15 2008 @@ -19,6 +19,7 @@ DelegateHolder = CLR.pypy.runtime.DelegateHolder LowLevelFlexSwitch = CLR.pypy.runtime.LowLevelFlexSwitch FlexSwitchCase = CLR.pypy.runtime.FlexSwitchCase +MethodIdMap = CLR.pypy.runtime.MethodIdMap OpCodes = System.Reflection.Emit.OpCodes InputArgs = CLR.pypy.runtime.InputArgs @@ -301,17 +302,22 @@ assert T is ootype.Object return ootype.cast_to_object(self.holder.GetFunc()) -class FlexSwitchConst(BaseConst): +class NativeObjectConst(BaseConst): + "GenConst for .NET objects" - def __init__(self, llflexswitch): - self.llflexswitch = llflexswitch + def __init__(self, obj): + "obj must casted to System.Object with dotnet.cliupcast" + self.obj = obj + + def getCliType(self): + return self.obj.GetType() def getobj(self): - return dotnet.cliupcast(self.llflexswitch, System.Object) + return self.obj def load(self, meth): index = self._get_index(meth) - self._load_from_array(meth, index, self.llflexswitch.GetType()) + self._load_from_array(meth, index, self.obj.GetType()) class Label(GenLabel): @@ -467,7 +473,18 @@ class GraphInfo: def __init__(self): self.args_manager = ArgsManager() - + self.methods = [] + self.method_id_map = MethodIdMap() + obj = dotnet.cliupcast(self.method_id_map, System.Object) + self.gv_method_id_map = NativeObjectConst(obj) + + def register_method(self, meth): + meth.method_id = len(self.methods) + self.methods.append(meth) + + def register_case(self, method_id, case): + self.method_id_map.add_case(method_id, case) + class MethodGenerator: @@ -486,7 +503,7 @@ self.inputargs_gv.append(GenArgVar(i, args[i])) self.delegatetype = delegatetype self.graphinfo = graphinfo - + graphinfo.register_method(self) self.gv_entrypoint = FunctionConst(delegatetype) self.gv_inputargs = None self.genconsts = {} @@ -500,6 +517,7 @@ self.gv_retvar = self.newlocalvar(restype) self.retlabel = self.newblock([self.gv_retvar]) + def _get_args_array(self, arglist): array = new_array(System.Type, len(arglist)+1) array[0] = System.Type.GetType("System.Object[]") @@ -622,8 +640,6 @@ class MainMethod(MethodGenerator): - method_id = 0 - def __init__(self, rgenop, name, restype, args, delegatetype): graphinfo = GraphInfo() MethodGenerator.__init__(self, rgenop, name, restype, args, delegatetype, graphinfo) @@ -656,14 +672,19 @@ self.emit_dispatch_block() def emit_jump_to_unknown_block(self, il_label): - # just throw an exception for now il = self.il + gv_method_id_map = self.graphinfo.gv_method_id_map + clitype = gv_method_id_map.getCliType() + meth_jumpto = clitype.GetMethod('jumpto') + + # jumpto = method_id_map.jumpto(jumpto, args) il.MarkLabel(il_label) - clitype = class2type(cUtils) - meth = clitype.GetMethod("throwInvalidBlockId") - #il.Emit(OpCodes.Ldloc, self.jumpto_var) - il.Emit(OpCodes.Ldc_I4, 4242) - il.Emit(OpCodes.Call, meth) + gv_method_id_map.load(self) + il.Emit(OpCodes.Ldloc, self.jumpto_var) + self.gv_inputargs.load(self) + il.Emit(OpCodes.Callvirt, meth_jumpto) + il.Emit(OpCodes.Stloc, self.jumpto_var) + il.Emit(OpCodes.Br, self.il_dispatch_block_label) class FlexCaseMethod(MethodGenerator): @@ -672,8 +693,6 @@ linkargs_gv = None linkargs_gv_map = None - method_id = 10 # XXX - def setup_flexswitches(self): pass @@ -701,6 +720,7 @@ func = self.gv_entrypoint.holder.GetFunc() func2 = clidowncast(func, FlexSwitchCase) self.parent_flexswitch.llflexswitch.add_case(self.value, func2) + self.graphinfo.register_case(self.method_id, func2) def emit_preamble(self): # the signature of the method is @@ -902,7 +922,8 @@ self.graph = graph self.linkargs_gv = linkargs_gv self.llflexswitch = LowLevelFlexSwitch() - self.gv_flexswitch = FlexSwitchConst(self.llflexswitch) + obj = dotnet.cliupcast(self.llflexswitch, System.Object) + self.gv_flexswitch = NativeObjectConst(obj) def add_case(self, gv_case): graph = self.graph Modified: pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/test/rgenop_tests.py Tue Oct 28 16:59:15 2008 @@ -564,7 +564,7 @@ return switch_goto_parent_block_runner -def make_switch_goto_between_flexswitches(T, rgenop): +def make_switch_two_switches(T, rgenop): """ def f(v0, v1): if v0 == 1: # switch @@ -604,15 +604,66 @@ builder.end() return gv_switch -def get_switch_goto_between_flexswitches_runner(T, RGenOp): - def switch_goto_between_flexswitches_runner(x, y): +def get_switch_two_switches_runner(T, RGenOp): + def switch_two_switches_runner(x, y): rgenop = RGenOp() - gv_switchfn = make_switch_goto_between_flexswitches(T, rgenop) + gv_switchfn = make_switch_two_switches(T, rgenop) switchfn = gv_switchfn.revealconst(T.Ptr(T.FUNC2)) res = switchfn(x, y) keepalive_until_here(rgenop) # to keep the code blocks alive return res - return switch_goto_between_flexswitches_runner + return switch_two_switches_runner + + +def make_switch_goto_between_cases(T, rgenop): + """ + def f(v0, v1): + if v0 == 1: # switch + firstblock: # label + return v1 + elif v0 == 2: + v1 = 42 + goto firstblock + else: + return 200 + """ + sigtoken = rgenop.sigToken(T.FUNC2) + builder, gv_switch, [gv0, gv1] = rgenop.newgraph(sigtoken, "switch") + builder.start_writing() + + const1 = rgenop.genconst(1) + const2 = rgenop.genconst(2) + const42 = rgenop.genconst(42) + const200 = rgenop.genconst(200) + + flexswitch, default_builder = builder.flexswitch(gv0, [gv1]) + + # outer default branch + default_builder.finish_and_return(sigtoken, const200) + + # case v0 == 1 + case_builder = flexswitch.add_case(const1) + args_gv = [gv1] + firstblock = case_builder.enter_next_block(args_gv) + [gv_x] = args_gv + case_builder.finish_and_return(sigtoken, gv_x) + + # case v0 == 2 + case_builder = flexswitch.add_case(const2) + case_builder.finish_and_goto([const42], firstblock) + + builder.end() + return gv_switch + +def get_switch_goto_between_cases_runner(T, RGenOp): + def switch_goto_between_cases_runner(x, y): + rgenop = RGenOp() + gv_switchfn = make_switch_goto_between_cases(T, rgenop) + switchfn = gv_switchfn.revealconst(T.Ptr(T.FUNC2)) + res = switchfn(x, y) + keepalive_until_here(rgenop) # to keep the code blocks alive + return res + return switch_goto_between_cases_runner def make_fact(T, rgenop): @@ -1292,8 +1343,8 @@ res = fn(42, 16) assert res == 16 - def test_switch_goto_between_flexswitches_compile(self): - fn = self.compile(get_switch_goto_between_flexswitches_runner(self.T, self.RGenOp), [int, int]) + def test_switch_two_switches_compile(self): + fn = self.compile(get_switch_two_switches_runner(self.T, self.RGenOp), [int, int]) res = fn(1, 2) assert res == 42 res = fn(1, 3) @@ -1301,6 +1352,15 @@ res = fn(2, 3) assert res == 200 + def test_switch_goto_between_cases_compile(self): + fn = self.compile(get_switch_goto_between_cases_runner(self.T, self.RGenOp), [int, int]) + res = fn(1, 2) + assert res == 2 + res = fn(2, 3) + assert res == 42 + res = fn(3, 4) + assert res == 200 + def test_fact_compile(self): fn = self.compile(get_fact_runner(self.T, self.RGenOp), [int]) res = fn(2) @@ -1554,9 +1614,9 @@ res = fnptr(42, 16) assert res == 16 - def test_switch_goto_between_flexswitches_direct(self): + def test_switch_two_switches_direct(self): rgenop = self.RGenOp() - gv_switchfn = make_switch_goto_between_flexswitches(self.T, rgenop) + gv_switchfn = make_switch_two_switches(self.T, rgenop) fnptr = self.cast(gv_switchfn, 2) res = fnptr(1, 2) assert res == 42 @@ -1565,6 +1625,17 @@ res = fnptr(2, 3) assert res == 200 + def test_switch_goto_between_cases_direct(self): + rgenop = self.RGenOp() + gv_switchfn = make_switch_goto_between_cases(self.T, rgenop) + fnptr = self.cast(gv_switchfn, 2) + res = fnptr(1, 2) + assert res == 2 + res = fnptr(2, 3) + assert res == 42 + res = fnptr(3, 4) + assert res == 200 + def test_large_switch_direct(self): rgenop = self.RGenOp() gv_switchfn = make_large_switch(self.T, rgenop) Modified: pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Tue Oct 28 16:59:15 2008 @@ -132,6 +132,32 @@ public delegate uint FlexSwitchCase(uint block, InputArgs args); + public class MethodIdMap + { + public FlexSwitchCase[] cases = new FlexSwitchCase[4]; + + public void add_case(int method_id, FlexSwitchCase c) + { + if (cases.Length <= method_id) + grow(); + cases[method_id] = c; + } + + public uint jumpto(uint blockid, InputArgs args) + { + uint method_id = (blockid & 0xFFFF0000) >> 16; + return cases[method_id](blockid, args); + } + + private void grow() + { + int newsize = cases.Length * 2; + FlexSwitchCase[] newcases = new FlexSwitchCase[newsize]; + Array.Copy(cases, newcases, cases.Length); + cases = newcases; + } + } + public class LowLevelFlexSwitch { public uint default_blockid = 0xFFFFFFFF; @@ -174,7 +200,7 @@ return cases[i](0, args); } return default_blockid; - } + } } @@ -365,7 +391,11 @@ public static void throwInvalidBlockId(uint blockid) { - throw new Exception(string.Format("Invalid block id: {0}", blockid)); + uint method_id = (blockid & 0xFFFF0000) >> 16; + uint block_num = (blockid & 0x0000FFFF); + string msg = string.Format("Invalid block id: 0x{0:X} ({1}, {2})", + blockid, method_id, block_num); + throw new Exception(msg); } public static void Serialize(object obj, string filename) From arigo at codespeak.net Tue Oct 28 17:00:39 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 17:00:39 +0100 (CET) Subject: [pypy-svn] r59490 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081028160039.7385F169FD4@codespeak.net> Author: arigo Date: Tue Oct 28 17:00:38 2008 New Revision: 59490 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: * Skip tests that don't make sense for us. * Checking an exception's exact message is an implementation detail. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Tue Oct 28 17:00:38 2008 @@ -532,7 +532,11 @@ def spamlists(): if verbose: print "Testing spamlist operations..." - import copy, xxsubtype as spam + try: + import copy, xxsubtype as spam + except ImportError, e: + if verbose: print "Skipped:", e + return def spamlist(l, memo=None): import xxsubtype as spam return spam.spamlist(l) @@ -568,7 +572,11 @@ def spamdicts(): if verbose: print "Testing spamdict operations..." - import copy, xxsubtype as spam + try: + import copy, xxsubtype as spam + except ImportError, e: + if verbose: print "Skipped:", e + return def spamdict(d, memo=None): import xxsubtype as spam sd = spam.spamdict() @@ -1100,7 +1108,8 @@ try: callable(*args) except exc, msg: - if not str(msg).startswith(expected): + # the exact msg is generally considered an implementation detail + if check_impl_detail and not str(msg).startswith(expected): raise TestFailed, "Message %r, expected %r" % (str(msg), expected) else: @@ -1555,7 +1564,11 @@ def classmethods_in_c(): if verbose: print "Testing C-based class methods..." - import xxsubtype as spam + try: + import xxsubtype as spam + except ImportError, e: + if verbose: print "Skipped:", e + return a = (1, 2, 3) d = {'abc': 123} x, a1, d1 = spam.spamlist.classmeth(*a, **d) @@ -1586,7 +1599,11 @@ def staticmethods_in_c(): if verbose: print "Testing C-based static methods..." - import xxsubtype as spam + try: + import xxsubtype as spam + except ImportError, e: + if verbose: print "Skipped:", e + return a = (1, 2, 3) d = {"abc": 123} x, a1, d1 = spam.spamlist.staticmeth(*a, **d) From arigo at codespeak.net Tue Oct 28 17:01:56 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 17:01:56 +0100 (CET) Subject: [pypy-svn] r59491 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081028160156.B8734169FD4@codespeak.net> Author: arigo Date: Tue Oct 28 17:01:55 2008 New Revision: 59491 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: A few calls to test_support.gc_collect(). Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Tue Oct 28 17:01:55 2008 @@ -1,7 +1,7 @@ # Test enhancements related to descriptors and new-style classes from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout -from test.test_support import check_impl_detail +from test.test_support import check_impl_detail, gc_collect from copy import deepcopy import warnings import types @@ -1286,6 +1286,7 @@ x.c = Counted() vereq(Counted.counter, 3) del x + gc_collect() vereq(Counted.counter, 0) class D(C): pass @@ -1294,6 +1295,7 @@ x.z = Counted() vereq(Counted.counter, 2) del x + gc_collect() vereq(Counted.counter, 0) class E(D): __slots__ = ['e'] @@ -1303,6 +1305,7 @@ x.e = Counted() vereq(Counted.counter, 3) del x + gc_collect() vereq(Counted.counter, 0) # Test cyclical leaks [SF bug 519621] @@ -1313,8 +1316,7 @@ s.a = [Counted(), s] vereq(Counted.counter, 1) s = None - import gc - gc.collect() + gc_collect() vereq(Counted.counter, 0) # Test lookup leaks [SF bug 572567] From antocuni at codespeak.net Tue Oct 28 17:12:20 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 28 Oct 2008 17:12:20 +0100 (CET) Subject: [pypy-svn] r59492 - pypy/branch/oo-jit/pypy/jit/codegen/cli/test Message-ID: <20081028161220.D3C81169F02@codespeak.net> Author: antocuni Date: Tue Oct 28 17:12:20 2008 New Revision: 59492 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py Log: cool, three more tests pass Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py Tue Oct 28 17:12:20 2008 @@ -10,12 +10,9 @@ def skip(self): py.test.skip('in progress') - more_promotes = skip - mixed_merges = skip remembers_across_mp = skip test_virtual_list_copy = skip test_raise_result_mixup = skip - test_two_promotions_in_call = skip test_promote_class = skip test_promote_class_vstruct = skip test_read___class___after_promotion = skip From fijal at codespeak.net Tue Oct 28 17:16:31 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 17:16:31 +0100 (CET) Subject: [pypy-svn] r59493 - in pypy/trunk/pypy/interpreter: pyparser test Message-ID: <20081028161631.E7629169F1C@codespeak.net> Author: fijal Date: Tue Oct 28 17:16:30 2008 New Revision: 59493 Modified: pypy/trunk/pypy/interpreter/pyparser/astbuilder.py pypy/trunk/pypy/interpreter/pyparser/asthelper.py pypy/trunk/pypy/interpreter/test/test_compiler.py Log: I *think* this is a proper try: except: finally: support (It doesn't introduce new ast node though) Modified: pypy/trunk/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/astbuilder.py Tue Oct 28 17:16:30 2008 @@ -982,8 +982,10 @@ def build_try_stmt(builder, nb): """ + try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break - ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite) + ['else' ':' suite] ['finally' ':' suite] + | 'try' ':' suite 'finally' ':' suite) # NB compile.c makes sure that the default except clause is last except_clause: 'except' [test [',' test]] @@ -1011,8 +1013,19 @@ if index < l: token = atoms[index] assert isinstance(token, TokenObject) - assert token.get_value() == 'else' - else_ = atoms[index+2] # skip ':' + if token.get_value() == 'else': + else_ = atoms[index+2] # skip ':' + index += 2 + if index < l: + token = atoms[index] + assert isinstance(token, TokenObject) + if token.get_value() != 'finally': + raise SyntaxError("Finally expected, got %s" % token.get_value()) + body1 = ast.TryExcept(body, handlers, else_, atoms[0].lineno) + res = ast.TryFinally(body1, atoms[index + 2], + atoms[0].lineno) + builder.push(res) + return builder.push(ast.TryExcept(body, handlers, else_, atoms[0].lineno)) ASTRULES_Template = { Modified: pypy/trunk/pypy/interpreter/pyparser/asthelper.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/asthelper.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/asthelper.py Tue Oct 28 17:16:30 2008 @@ -15,7 +15,8 @@ while clause_length < len(tokens): token = tokens[clause_length] if isinstance(token, TokenObject) and \ - (token.get_value() == 'except' or token.get_value() == 'else'): + (token.get_value() == 'except' or token.get_value() == 'else' + or token.get_value() == 'finally'): break clause_length += 1 if clause_length == 3: Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_compiler.py (original) +++ pypy/trunk/pypy/interpreter/test/test_compiler.py Tue Oct 28 17:16:30 2008 @@ -142,7 +142,6 @@ assert ex.match(self.space, self.space.w_SyntaxError) def test_try_except_finally(self): - py.test.skip("FAILS!") s = py.code.Source(""" def f(): try: @@ -659,6 +658,8 @@ self.space.config.objspace.pyversion = "2.4" self.compiler = PythonAstCompiler(self.space, "2.4") + def test_try_except_finally(self): + py.test.skip("unsupported") class AppTestOptimizer: def test_constant_fold_add(self): From arigo at codespeak.net Tue Oct 28 17:56:23 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 17:56:23 +0100 (CET) Subject: [pypy-svn] r59494 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081028165623.819F616A083@codespeak.net> Author: arigo Date: Tue Oct 28 17:56:21 2008 New Revision: 59494 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: No gc.get_objects(). Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Tue Oct 28 17:56:21 2008 @@ -1321,15 +1321,18 @@ # Test lookup leaks [SF bug 572567] import sys,gc - class G(object): - def __cmp__(self, other): - return 0 - g = G() - orig_objects = len(gc.get_objects()) - for i in xrange(10): - g==g - new_objects = len(gc.get_objects()) - vereq(orig_objects, new_objects) + if check_impl_detail: # no gc.get_objects() on non-CPython + # implementations, but no leaks either :-) + class G(object): + def __cmp__(self, other): + return 0 + g = G() + orig_objects = len(gc.get_objects()) + for i in xrange(10): + g==g + new_objects = len(gc.get_objects()) + vereq(orig_objects, new_objects) + class H(object): __slots__ = ['a', 'b'] def __init__(self): From fijal at codespeak.net Tue Oct 28 18:07:56 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 18:07:56 +0100 (CET) Subject: [pypy-svn] r59495 - in pypy/trunk/pypy/interpreter: pyparser test Message-ID: <20081028170756.01BAB16A0C6@codespeak.net> Author: fijal Date: Tue Oct 28 18:07:56 2008 New Revision: 59495 Modified: pypy/trunk/pypy/interpreter/pyparser/astbuilder.py pypy/trunk/pypy/interpreter/test/test_compiler.py Log: a test and a fix Modified: pypy/trunk/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/astbuilder.py Tue Oct 28 18:07:56 2008 @@ -1015,7 +1015,7 @@ assert isinstance(token, TokenObject) if token.get_value() == 'else': else_ = atoms[index+2] # skip ':' - index += 2 + index += 3 if index < l: token = atoms[index] assert isinstance(token, TokenObject) Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_compiler.py (original) +++ pypy/trunk/pypy/interpreter/test/test_compiler.py Tue Oct 28 18:07:56 2008 @@ -152,6 +152,18 @@ return 3 """) self.compiler.compile(str(s), '', 'exec', 0) + s = py.code.Source(""" + def f(): + try: + 1/0 + except: + pass + else: + pass + finally: + return 2 + """) + self.compiler.compile(str(s), '', 'exec', 0) def test_toplevel_docstring(self): space = self.space From xoraxax at codespeak.net Tue Oct 28 18:12:39 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 28 Oct 2008 18:12:39 +0100 (CET) Subject: [pypy-svn] r59496 - pypy/build/benchmem Message-ID: <20081028171239.32AC816A0C6@codespeak.net> Author: xoraxax Date: Tue Oct 28 18:12:38 2008 New Revision: 59496 Modified: pypy/build/benchmem/report_graphic.py Log: I did not notice Fijals appprofile benchrunner so I inserted the wrong filter ... Did no reviewer spot it? :) Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Tue Oct 28 18:12:38 2008 @@ -10,7 +10,7 @@ resultset = runbench.ResultSet() resultset.parse(py.path.local(filename), True) # by default it shows all graphs, a bit boring, but educating ;) - for name, results in resultset.filter(benchtype="objsizes").getname2results(): + for name, results in resultset.filter(benchtype="appprofiles").getname2results(): for result in results: lgt = len(result.snapshots) x = [float(i)/lgt for i in range(lgt)] From xoraxax at codespeak.net Tue Oct 28 18:13:26 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 28 Oct 2008 18:13:26 +0100 (CET) Subject: [pypy-svn] r59497 - pypy/build/benchmem Message-ID: <20081028171326.A9BCD16A0C6@codespeak.net> Author: xoraxax Date: Tue Oct 28 18:13:26 2008 New Revision: 59497 Modified: pypy/build/benchmem/runbench.py Log: Also recognize segments that are readable, writable and executable as data segments. Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Tue Oct 28 18:13:26 2008 @@ -23,6 +23,7 @@ def __init__(self, executable, logpath, options): self.executable = executable self.executable_full_path = py.path.local.sysfind(executable) + assert self.executable_full_path self.logpath = py.path.local(logpath) self.logstream = self.logpath.open("a") self.options = options @@ -404,7 +405,8 @@ if kind is not None: if kind is self.CODE and mapping.mode != 'r-xp': matches = False - if kind is self.DATA and mapping.mode != 'rw-p': + # XXX why is the data mapping sometimes executable? + if kind is self.DATA and mapping.mode not in ('rw-p', 'rwxp'): matches = False if matches != bool(inv): From fijal at codespeak.net Tue Oct 28 18:18:38 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 18:18:38 +0100 (CET) Subject: [pypy-svn] r59498 - pypy/trunk/pypy/interpreter/test Message-ID: <20081028171838.67DF4169F26@codespeak.net> Author: fijal Date: Tue Oct 28 18:18:38 2008 New Revision: 59498 Added: pypy/trunk/pypy/interpreter/test/test_zpy.py - copied unchanged from r59494, pypy/trunk/pypy/interpreter/test/test_py.py pypy/trunk/pypy/interpreter/test/test_zzz.py (contents, props changed) Removed: pypy/trunk/pypy/interpreter/test/test_pickle.py pypy/trunk/pypy/interpreter/test/test_py.py Modified: pypy/trunk/pypy/interpreter/test/test_code.py Log: Shuffle stuff around so slow tests are at the end (zzz and zpy) Modified: pypy/trunk/pypy/interpreter/test/test_code.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_code.py (original) +++ pypy/trunk/pypy/interpreter/test/test_code.py Tue Oct 28 18:18:38 2008 @@ -142,15 +142,6 @@ assert d1['f'].func_code == d2['f'].func_code assert hash(d1['f'].func_code) == hash(d2['f'].func_code) - def test_inspect(self): - if not hasattr(len, 'func_code'): - skip("Cannot run this test if builtins have no func_code") - import inspect - args, varargs, varkw = inspect.getargs(len.func_code) - assert args == ['obj'] - assert varargs is None - assert varkw is None - def test_repr(self): def f(): xxx @@ -160,4 +151,3 @@ 'line'] for i in expected: assert i in res - Added: pypy/trunk/pypy/interpreter/test/test_zzz.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/interpreter/test/test_zzz.py Tue Oct 28 18:18:38 2008 @@ -0,0 +1,456 @@ +import py +from pypy import conftest + +class AppTestSlow: + def setup_class(cls): + space = gettestobjspace() + cls.space = space + if py.test.config.option.runappdirect: + filename = __file__ + else: + filename = gateway.__file__ + + if filename[-3:] != '.py': + filename = filename[:-1] + + cls.w_file = space.wrap(filename) + + def test_inspect(self): + if not hasattr(len, 'func_code'): + skip("Cannot run this test if builtins have no func_code") + import inspect + args, varargs, varkw = inspect.getargs(len.func_code) + assert args == ['obj'] + assert varargs is None + assert varkw is None + +def _attach_helpers(space): + from pypy.interpreter import pytraceback + def hide_top_frame(space, w_frame): + w_last = None + while w_frame.f_back: + w_last = w_frame + w_frame = w_frame.f_back + assert w_last + w_saved = w_last.f_back + w_last.f_back = None + return w_saved + + def restore_top_frame(space, w_frame, w_saved): + while w_frame.f_back: + w_frame = w_frame.f_back + w_frame.f_back = w_saved + + def read_exc_type(space, w_frame): + if w_frame.last_exception is None: + return space.w_None + else: + return w_frame.last_exception.w_type + + from pypy.interpreter import gateway + + hide_gw = gateway.interp2app(hide_top_frame) + space.setitem(space.builtin.w_dict, + space.wrap('hide_top_frame'), + space.wrap(hide_gw)) + restore_gw = gateway.interp2app(restore_top_frame) + space.setitem(space.builtin.w_dict, + space.wrap('restore_top_frame'), + space.wrap(restore_gw)) + + read_exc_type_gw = gateway.interp2app(read_exc_type) + space.setitem(space.builtin.w_dict, + space.wrap('read_exc_type'), + space.wrap(read_exc_type_gw)) + +def _detatch_helpers(space): + space.delitem(space.builtin.w_dict, + space.wrap('hide_top_frame')) + space.delitem(space.builtin.w_dict, + space.wrap('restore_top_frame')) + +class AppTestInterpObjectPickling: + + def setup_class(cls): + if conftest.option.runappdirect: + py.test.skip("not for py.test -A") + _attach_helpers(cls.space) + + def teardown_class(cls): + _detatch_helpers(cls.space) + + def test_pickle_code(self): + def f(): + return 42 + import pickle + code = f.func_code + pckl = pickle.dumps(code) + result = pickle.loads(pckl) + assert code == result + + def test_pickle_global_func(self): + import new + mod = new.module('mod') + import sys + sys.modules['mod'] = mod + try: + def func(): + return 42 + mod.__dict__['func'] = func + func.__module__ = 'mod' + import pickle + pckl = pickle.dumps(func) + result = pickle.loads(pckl) + assert func is result + finally: + del sys.modules['mod'] + + def test_pickle_not_imported_module(self): + import new + mod = new.module('mod') + mod.__dict__['a'] = 1 + import pickle + pckl = pickle.dumps(mod) + result = pickle.loads(pckl) + assert mod.__name__ == result.__name__ + assert mod.__dict__ == result.__dict__ + + def test_pickle_builtin_func(self): + import pickle + pckl = pickle.dumps(map) + result = pickle.loads(pckl) + assert map is result + + def test_pickle_non_top_reachable_func(self): + def func(): + return 42 + global a + a = 42 + del globals()['test_pickle_non_top_reachable_func'] + import pickle + pckl = pickle.dumps(func) + result = pickle.loads(pckl) + assert func.func_name == result.func_name + assert func.func_closure == result.func_closure + assert func.func_code == result.func_code + assert func.func_defaults == result.func_defaults + assert func.func_dict == result.func_dict + assert func.func_doc == result.func_doc + assert func.func_globals == result.func_globals + + def test_pickle_cell(self): + def g(): + x = [42] + def f(): + x[0] += 1 + return x + return f.func_closure[0] + import pickle + cell = g() + pckl = pickle.dumps(cell) + result = pickle.loads(pckl) + assert cell == result + assert not (cell != result) + + def test_pickle_frame(self): + #import sys + # avoid creating a closure for now + def f(): + try: + raise Exception() + except: + import sys + exc_type, exc, tb = sys.exc_info() + return tb.tb_frame + import pickle + f1 = f() + saved = hide_top_frame(f1) + pckl = pickle.dumps(f1) + restore_top_frame(f1, saved) + f2 = pickle.loads(pckl) + + assert type(f1) is type(f2) + assert dir(f1) == dir(f2) + assert f1.__doc__ == f2.__doc__ + assert f2.f_back is None # because we pruned it + assert f1.f_builtins is f2.f_builtins + assert f1.f_code == f2.f_code + assert f1.f_exc_traceback is f2.f_exc_traceback + assert f1.f_exc_type is f2.f_exc_type + assert f1.f_exc_value is f2.f_exc_value + assert f1.f_lasti == f2.f_lasti + assert f1.f_lineno == f2.f_lineno + assert f1.f_restricted is f2.f_restricted + assert f1.f_trace is f2.f_trace + + def test_pickle_frame_with_exc(self): + #import sys + # avoid creating a closure for now + del self + def f(): + try: + raise ValueError + except: + import sys, pickle + f = sys._getframe() + saved = hide_top_frame(f) + pckl = pickle.dumps(f) + restore_top_frame(f, saved) + return pckl + + import pickle + pckl = f() + f2 = pickle.loads(pckl) + + assert read_exc_type(f2) is ValueError + + def test_pickle_frame_clos(self): + # similar to above, therefore skipping the asserts. + # we just want to see that the closure works + import sys # this is the difference! + def f(): + try: + raise Exception() + except: + exc_type, exc, tb = sys.exc_info() + return tb.tb_frame + import pickle + f1 = f() + saved = hide_top_frame(f1) + pckl = pickle.dumps(f1) + restore_top_frame(f1, saved) + f2 = pickle.loads(pckl) + + def test_pickle_traceback(self): + def f(): + try: + raise Exception() + except: + from sys import exc_info + exc_type, exc, tb = exc_info() + return tb + import pickle + tb = f() + saved = hide_top_frame(tb.tb_frame) + pckl = pickle.dumps(tb) + result = pickle.loads(pckl) + + assert type(tb) is type(result) + assert tb.tb_lasti == result.tb_lasti + assert tb.tb_lineno == result.tb_lineno + assert tb.tb_next == result.tb_next + + restore_top_frame(tb.tb_frame, saved) + + def test_pickle_module(self): + import pickle + mod = pickle + pckl = pickle.dumps(mod) + result = pickle.loads(pckl) + assert mod is result + + def test_pickle_moduledict(self): + import pickle + moddict = pickle.__dict__ + pckl = pickle.dumps(moddict) + result = pickle.loads(pckl) + assert moddict is result + + def test_pickle_bltins_module(self): + import pickle + mod = __builtins__ + pckl = pickle.dumps(mod) + result = pickle.loads(pckl) + assert mod is result + + def test_pickle_buffer(self): + skip("Can't pickle buffer objects on top of CPython either. " + "Do we really need it?") + import pickle + a = buffer('ABCDEF') + pckl = pickle.dumps(a) + result = pickle.loads(pckl) + assert a == result + + def test_pickle_complex(self): + import pickle + a = complex(1.23,4.567) + pckl = pickle.dumps(a) + result = pickle.loads(pckl) + assert a == result + + def test_pickle_method(self): + class myclass(object): + def f(self): + return 42 + def __reduce__(self): + return (myclass, ()) + import pickle, sys, new + myclass.__module__ = 'mod' + myclass_inst = myclass() + mod = new.module('mod') + mod.myclass = myclass + sys.modules['mod'] = mod + try: + method = myclass_inst.f + pckl = pickle.dumps(method) + result = pickle.loads(pckl) + # we cannot compare the objects, because the method will be a fresh one + assert method() == result() + finally: + del sys.modules['mod'] + + def test_pickle_staticmethod(self): + class myclass(object): + def f(): + return 42 + f = staticmethod(f) + import pickle + method = myclass.f + pckl = pickle.dumps(method) + result = pickle.loads(pckl) + assert method() == result() + + def test_pickle_classmethod(self): + class myclass(object): + def f(cls): + return cls + f = classmethod(f) + import pickle, sys, new + myclass.__module__ = 'mod' + mod = new.module('mod') + mod.myclass = myclass + sys.modules['mod'] = mod + try: + method = myclass.f + pckl = pickle.dumps(method) + result = pickle.loads(pckl) + assert method() == result() + finally: + del sys.modules['mod'] + + def test_pickle_sequenceiter(self): + ''' + In PyPy there is no distinction here between listiterator and + tupleiterator that is why you will find no test_pickle_listiter nor + test_pickle_tupleiter here, just this test. + ''' + import pickle + liter = iter([3,9,6,12,15,17,19,111]) + liter.next() + pckl = pickle.dumps(liter) + result = pickle.loads(pckl) + liter.next() + result.next() + assert type(liter) is type(result) + raises(TypeError, len, liter) + assert list(liter) == list(result) + + def test_pickle_reversesequenceiter(self): + import pickle + liter = reversed([3,9,6,12,15,17,19,111]) + liter.next() + pckl = pickle.dumps(liter) + result = pickle.loads(pckl) + liter.next() + result.next() + assert type(liter) is type(result) + raises(TypeError, len, liter) + assert list(liter) == list(result) + + def test_pickle_dictiter(self): + import pickle + tdict = {'2':2, '3':3, '5':5} + diter = iter(tdict) + diter.next() + pckl = pickle.dumps(diter) + result = pickle.loads(pckl) + raises(TypeError, len, diter) + assert list(diter) == list(result) + + def test_pickle_enum(self): + import pickle + e = enumerate(range(10)) + e.next() + e.next() + pckl = pickle.dumps(e) + result = pickle.loads(pckl) + e.next() + result.next() + assert type(e) is type(result) + assert list(e) == list(result) + + def test_pickle_xrangeiter(self): + import pickle + riter = iter(xrange(5)) + riter.next() + riter.next() + pckl = pickle.dumps(riter) + result = pickle.loads(pckl) + assert type(riter) is type(result) + assert list(result) == [2,3,4] + + def test_pickle_generator(self): + import new + mod = new.module('mod') + import sys + sys.modules['mod'] = mod + try: + def giveme(n): + x = 0 + while x < n: + yield x + x += 1 + import pickle + mod.giveme = giveme + giveme.__module__ = mod + g1 = mod.giveme(10) + #g1.next() + #g1.next() + pckl = pickle.dumps(g1) + g2 = pickle.loads(pckl) + assert list(g1) == list(g2) + finally: + del sys.modules['mod'] + + def test_pickle_generator_blk(self): + # same as above but with the generator inside a block + import new + mod = new.module('mod') + import sys + sys.modules['mod'] = mod + try: + def giveme(n): + x = 0 + while x < n: + yield x + x += 1 + import pickle + mod.giveme = giveme + giveme.__module__ = mod + g1 = mod.giveme(10) + g1.next() + g1.next() + pckl = pickle.dumps(g1) + g2 = pickle.loads(pckl) + assert list(g1) == list(g2) + finally: + del sys.modules['mod'] + + def test_pickle_builtin_method(self): + import pickle + + a_list = [1] + meth1 = a_list.append + pckl = pickle.dumps(meth1) + meth2 = pickle.loads(pckl) + meth1(1) + meth2(2) + assert a_list == [1, 1] + assert meth2.im_self == [1, 2] + + unbound_meth = list.append + unbound_meth2 = pickle.loads(pickle.dumps(unbound_meth)) + l = [] + unbound_meth2(l, 1) + assert l == [1] From cfbolz at codespeak.net Tue Oct 28 18:47:21 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 28 Oct 2008 18:47:21 +0100 (CET) Subject: [pypy-svn] r59499 - in pypy/trunk/pypy/module/thread: . test Message-ID: <20081028174721.F182C169FD4@codespeak.net> Author: cfbolz Date: Tue Oct 28 18:47:19 2008 New Revision: 59499 Modified: pypy/trunk/pypy/module/thread/os_lock.py pypy/trunk/pypy/module/thread/test/test_lock.py Log: add __enter__ and __exit__ methods to locks Modified: pypy/trunk/pypy/module/thread/os_lock.py ============================================================================== --- pypy/trunk/pypy/module/thread/os_lock.py (original) +++ pypy/trunk/pypy/module/thread/os_lock.py Tue Oct 28 18:47:19 2008 @@ -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.baseobjspace import Wrappable -from pypy.interpreter.gateway import ObjSpace, interp2app +from pypy.interpreter.gateway import ObjSpace, interp2app, Arguments from pypy.interpreter.typedef import TypeDef # Force the declaration of the type 'thread.LockType' for RPython @@ -63,6 +63,12 @@ else: return space.w_True + def descr__enter__(self, space): + self.descr_lock_acquire(space) + return self + + def descr__exit__(self, space, __args__): + self.descr_lock_release(space) descr_acquire = interp2app(Lock.descr_lock_acquire, unwrap_spec=['self', ObjSpace, int]) @@ -70,6 +76,11 @@ unwrap_spec=['self', ObjSpace]) descr_locked = interp2app(Lock.descr_lock_locked, unwrap_spec=['self', ObjSpace]) +descr__enter__ = interp2app(Lock.descr__enter__, + unwrap_spec=['self', ObjSpace]) +descr__exit__ = interp2app(Lock.descr__exit__, + unwrap_spec=['self', ObjSpace, Arguments]) + Lock.typedef = TypeDef("thread.lock", __doc__ = """\ @@ -86,6 +97,8 @@ acquire = descr_acquire, release = descr_release, locked = descr_locked, + __enter__ = descr__enter__, + __exit__ = descr__exit__, # Obsolete synonyms acquire_lock = descr_acquire, release_lock = descr_release, Modified: pypy/trunk/pypy/module/thread/test/test_lock.py ============================================================================== --- pypy/trunk/pypy/module/thread/test/test_lock.py (original) +++ pypy/trunk/pypy/module/thread/test/test_lock.py Tue Oct 28 18:47:19 2008 @@ -29,6 +29,25 @@ assert lock.locked() is True assert feedback == [42] + def test_lock_in_with(self): + import thread + lock = thread.allocate_lock() + feedback = [] + lock.acquire() + def f(): + self.busywait(0.25) + feedback.append(42) + lock.release() + assert lock.locked() is True + thread.start_new_thread(f, ()) + exec """ +from __future__ import with_statement +if 1: + with lock: + assert lock.locked() is True + assert feedback == [42] +""" in {"lock": lock, "feedback": feedback} + assert lock.locked() is False def test_compile_lock(): from pypy.rlib import rgc From arigo at codespeak.net Tue Oct 28 18:47:30 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 18:47:30 +0100 (CET) Subject: [pypy-svn] r59500 - pypy/trunk/pypy/interpreter Message-ID: <20081028174730.CD63E16A000@codespeak.net> Author: arigo Date: Tue Oct 28 18:47:30 2008 New Revision: 59500 Modified: pypy/trunk/pypy/interpreter/typedef.py Log: Go over the list of built-in types in typedef.py and mark 'acceptable_as_base_class = False' for most of them, just following what CPython does. This should reduce the size of the pypy-c a tiny bit. Modified: pypy/trunk/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/pypy/interpreter/typedef.py (original) +++ pypy/trunk/pypy/interpreter/typedef.py Tue Oct 28 18:47:30 2008 @@ -499,6 +499,7 @@ __objclass__ = GetSetProperty(GetSetProperty.descr_get_objclass), __doc__ = interp_attrproperty('doc', cls=GetSetProperty), ) +GetSetProperty.acceptable_as_base_class = False class Member(Wrappable): @@ -559,6 +560,7 @@ __name__ = interp_attrproperty('name', cls=Member), __objclass__ = interp_attrproperty_w('w_cls', cls=Member), ) +Member.acceptable_as_base_class = False # ____________________________________________________________ # @@ -649,12 +651,14 @@ co_flags = GetSetProperty(fget_co_flags, cls=Code), co_consts = GetSetProperty(fget_co_consts, cls=Code), ) +Code.acceptable_as_base_class = False Frame.typedef = TypeDef('internal-frame', f_code = GetSetProperty(Frame.fget_code), f_locals = GetSetProperty(Frame.fget_getdictscope), f_globals = interp_attrproperty_w('w_globals', cls=Frame), ) +Frame.acceptable_as_base_class = False PyCode.typedef = TypeDef('code', __new__ = interp2app(PyCode.descr_code__new__.im_func), @@ -679,6 +683,7 @@ co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), co_lnotab = interp_attrproperty('co_lnotab', cls=PyCode), ) +PyCode.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', __reduce__ = interp2app(PyFrame.descr__reduce__, @@ -696,6 +701,7 @@ f_exc_traceback = GetSetProperty(PyFrame.fget_f_exc_traceback), f_restricted = GetSetProperty(PyFrame.fget_f_restricted), **Frame.typedef.rawdict) +PyFrame.acceptable_as_base_class = False Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func, @@ -756,6 +762,7 @@ __module__ = getset___module__, __weakref__ = make_weakref_descr(Function), ) +Function.acceptable_as_base_class = False Method.typedef = TypeDef("method", __new__ = interp2app(Method.descr_method__new__.im_func), @@ -774,6 +781,7 @@ unwrap_spec=['self', ObjSpace]), __weakref__ = make_weakref_descr(Method), ) +Method.acceptable_as_base_class = False StaticMethod.typedef = TypeDef("staticmethod", __doc__ = """staticmethod(function) -> static method @@ -827,6 +835,7 @@ '__repr__': interp2app(BuiltinFunction.descr_function_repr), }) del BuiltinFunction.typedef.rawdict['__get__'] +BuiltinFunction.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", __reduce__ = interp2app(PyTraceback.descr__reduce__, @@ -838,6 +847,7 @@ tb_lineno = interp_attrproperty('lineno', cls=PyTraceback), tb_next = interp_attrproperty('next', cls=PyTraceback), ) +PyTraceback.acceptable_as_base_class = False GeneratorIterator.typedef = TypeDef("generator", __reduce__ = interp2app(GeneratorIterator.descr__reduce__, @@ -856,6 +866,7 @@ gi_frame = interp_attrproperty('frame', cls=GeneratorIterator), __weakref__ = make_weakref_descr(GeneratorIterator), ) +GeneratorIterator.acceptable_as_base_class = False Cell.typedef = TypeDef("cell", __eq__ = interp2app(Cell.descr__eq__, @@ -867,6 +878,7 @@ __setstate__ = interp2app(Cell.descr__setstate__, unwrap_spec=['self', ObjSpace, W_Root]), ) +Cell.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", __repr__ = interp2app(Ellipsis.descr__repr__), @@ -876,6 +888,7 @@ NotImplemented.typedef = TypeDef("NotImplemented", __repr__ = interp2app(NotImplemented.descr__repr__), ) +NotImplemented.acceptable_as_base_class = False SuspendedUnroller.typedef = TypeDef("SuspendedUnroller") SuspendedUnroller.acceptable_as_base_class = False From fijal at codespeak.net Tue Oct 28 18:55:09 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 18:55:09 +0100 (CET) Subject: [pypy-svn] r59501 - pypy/trunk/pypy/interpreter/test Message-ID: <20081028175509.94AD7169FEC@codespeak.net> Author: fijal Date: Tue Oct 28 18:55:09 2008 New Revision: 59501 Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py pypy/trunk/pypy/interpreter/test/test_zzz.py Log: * fix imports * skip this on cpy2.4 Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_compiler.py (original) +++ pypy/trunk/pypy/interpreter/test/test_compiler.py Tue Oct 28 18:55:09 2008 @@ -629,11 +629,11 @@ def skip_on_2_4(self): py.test.skip("syntax not supported by the CPython 2.4 compiler") test_continue_in_nested_finally = skip_on_2_4 + test_try_except_finally = skip_on_2_4 elif sys.version_info > (2, 4): def skip_on_2_5(self): py.test.skip("syntax changed in CPython 2.5 compiler") test_yield_in_finally = skip_on_2_5 - class TestPythonAstCompiler_25_grammar(BaseTestCompiler): def setup_method(self, method): Modified: pypy/trunk/pypy/interpreter/test/test_zzz.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_zzz.py (original) +++ pypy/trunk/pypy/interpreter/test/test_zzz.py Tue Oct 28 18:55:09 2008 @@ -1,5 +1,7 @@ import py from pypy import conftest +from pypy.conftest import gettestobjspace +from pypy.interpreter import gateway class AppTestSlow: def setup_class(cls): From cfbolz at codespeak.net Tue Oct 28 19:01:46 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 28 Oct 2008 19:01:46 +0100 (CET) Subject: [pypy-svn] r59502 - in pypy/trunk/pypy/interpreter: . test Message-ID: <20081028180146.361D916A09A@codespeak.net> Author: cfbolz Date: Tue Oct 28 19:01:45 2008 New Revision: 59502 Modified: pypy/trunk/pypy/interpreter/generator.py pypy/trunk/pypy/interpreter/pytraceback.py pypy/trunk/pypy/interpreter/test/test_generator.py Log: you can pass None as a valid traceback argument to generator.throw Modified: pypy/trunk/pypy/interpreter/generator.py ============================================================================== --- pypy/trunk/pypy/interpreter/generator.py (original) +++ pypy/trunk/pypy/interpreter/generator.py Tue Oct 28 19:01:45 2008 @@ -66,7 +66,7 @@ self.frame.f_back = None self.running = False - def descr_throw(self, w_type, w_val=None, w_tb=NoneNotWrapped): + def descr_throw(self, w_type, w_val=None, w_tb=None): """throw(typ[,val[,tb]]) -> raise exception in generator, return next yielded value or raise StopIteration.""" return self.throw(w_type, w_val, w_tb) @@ -77,7 +77,10 @@ space = self.space msg = "throw() third argument must be a traceback object" - tb = check_traceback(space, w_tb, msg) + if space.is_w(w_tb, space.w_None): + tb = None + else: + tb = check_traceback(space, w_tb, msg) operr = OperationError(w_type, w_val, tb) operr.normalize_exception(space) @@ -96,7 +99,8 @@ """close(arg) -> raise GeneratorExit inside generator.""" space = self.space try: - w_retval = self.throw(space.w_GeneratorExit, space.w_None, None) + w_retval = self.throw(space.w_GeneratorExit, space.w_None, + space.w_None) except OperationError, e: if e.match(space, space.w_StopIteration) or \ e.match(space, space.w_GeneratorExit): Modified: pypy/trunk/pypy/interpreter/pytraceback.py ============================================================================== --- pypy/trunk/pypy/interpreter/pytraceback.py (original) +++ pypy/trunk/pypy/interpreter/pytraceback.py Tue Oct 28 19:01:45 2008 @@ -66,12 +66,8 @@ def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback - if w_tb is not None: - tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, - space.gettypeobject(PyTraceback.typedef))): - raise OperationError(space.w_TypeError, space.wrap(msg)) - else: - tb = None + tb = space.interpclass_w(w_tb) + if tb is None or not space.is_true(space.isinstance(tb, + space.gettypeobject(PyTraceback.typedef))): + raise OperationError(space.w_TypeError, space.wrap(msg)) return tb - Modified: pypy/trunk/pypy/interpreter/test/test_generator.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_generator.py (original) +++ pypy/trunk/pypy/interpreter/test/test_generator.py Tue Oct 28 19:01:45 2008 @@ -94,6 +94,13 @@ # String exceptions are allowed (with DeprecationWarning) assert g.throw("Error") == 3 raises(StopIteration, g.throw, "Error") + + def test_throw6(self): + def f(): + yield 2 + g = f() + raises(NameError, g.throw, NameError, "Error", None) + def test_throw_fail(self): def f(): From cfbolz at codespeak.net Tue Oct 28 19:01:59 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 28 Oct 2008 19:01:59 +0100 (CET) Subject: [pypy-svn] r59503 - pypy/trunk/lib-python Message-ID: <20081028180159.72D4F16A0AC@codespeak.net> Author: cfbolz Date: Tue Oct 28 19:01:58 2008 New Revision: 59503 Modified: pypy/trunk/lib-python/failure_list.txt Log: this is done Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Tue Oct 28 19:01:58 2008 @@ -20,7 +20,6 @@ test_commands ! unknown test_compile ! test_leading_newlines: impl detail; the rest: not good test_compiler ! unknown -test_contextlib ! should be fixed, probably not too hard test_ctypes ! implementation details but also some real crashes test_datetime ! the two test_negative_*() look like real bugs test_decimal missing decimal.ROUND_05UP From arigo at codespeak.net Tue Oct 28 19:07:08 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 19:07:08 +0100 (CET) Subject: [pypy-svn] r59504 - pypy/trunk/pypy/interpreter Message-ID: <20081028180708.01AB11683EA@codespeak.net> Author: arigo Date: Tue Oct 28 19:07:07 2008 New Revision: 59504 Modified: pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/interpreter/gateway.py Log: Change the meaning of 'bool' in unwrap_spec: instead of just using is_true(), it should only accept booleans and maybe integers too. Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Tue Oct 28 19:07:07 2008 @@ -981,6 +981,11 @@ buffer = self.buffer_w(w_obj) return buffer.as_str() + def bool_w(self, w_obj): + # Unwraps a bool, also accepting an int for compatibility. + # This is here mostly just for gateway.int_unwrapping_space_method(). + return bool(self.int_w(w_obj)) + def warn(self, msg, w_warningcls): self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): import warnings Modified: pypy/trunk/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/gateway.py (original) +++ pypy/trunk/pypy/interpreter/gateway.py Tue Oct 28 19:07:07 2008 @@ -374,8 +374,6 @@ return 'r_longlong_w' elif typ is r_uint: return 'uint_w' - elif typ is bool: - return 'is_true' else: return typ.__name__ + '_w' From arigo at codespeak.net Tue Oct 28 19:12:51 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 28 Oct 2008 19:12:51 +0100 (CET) Subject: [pypy-svn] r59505 - in pypy/trunk/pypy/interpreter: . test Message-ID: <20081028181251.94700169F6A@codespeak.net> Author: arigo Date: Tue Oct 28 19:12:51 2008 New Revision: 59505 Modified: pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/interpreter/gateway.py pypy/trunk/pypy/interpreter/test/test_gateway.py Log: Add the unwrap_spec string 'nonnegint'. Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Tue Oct 28 19:12:51 2008 @@ -986,6 +986,15 @@ # This is here mostly just for gateway.int_unwrapping_space_method(). return bool(self.int_w(w_obj)) + def nonnegint_w(self, w_obj): + # Like space.int_w(), but raises an app-level ValueError if + # the integer is negative. Mostly here for gateway.py. + value = self.int_w(w_obj) + if value < 0: + raise OperationError(self.w_ValueError, + self.wrap("expected a non-negative integer")) + return value + def warn(self, msg, w_warningcls): self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): import warnings Modified: pypy/trunk/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/gateway.py (original) +++ pypy/trunk/pypy/interpreter/gateway.py Tue Oct 28 19:12:51 2008 @@ -123,6 +123,9 @@ def visit_bufferstr(self, el, app_sig): self.checked_space_method(el, app_sig) + def visit_nonnegint(self, el, app_sig): + self.checked_space_method(el, app_sig) + def visit__Wrappable(self, el, app_sig): name = el.__name__ argname = self.orig_arg() @@ -224,6 +227,9 @@ def visit_bufferstr(self, typ): self.run_args.append("space.bufferstr_w(%s)" % (self.scopenext(),)) + def visit_nonnegint(self, typ): + self.run_args.append("space.nonnegint_w(%s)" % (self.scopenext(),)) + def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) @@ -339,6 +345,9 @@ def visit_bufferstr(self, typ): self.unwrap.append("space.bufferstr_w(%s)" % (self.nextarg(),)) + def visit_nonnegint(self, typ): + self.unwrap.append("space.nonnegint_w(%s)" % (self.nextarg(),)) + def make_fastfunc(unwrap_spec, func): unwrap_info = UnwrapSpec_FastFunc_Unwrap() unwrap_info.apply_over(unwrap_spec) Modified: pypy/trunk/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_gateway.py (original) +++ pypy/trunk/pypy/interpreter/test/test_gateway.py Tue Oct 28 19:12:51 2008 @@ -165,6 +165,21 @@ assert self.space.eq_w(space.call_function(w_app_g, space.wrap(True)), space.wrap(True)) + def test_interp2app_unwrap_spec_nonnegint(self): + space = self.space + w = space.wrap + def g(space, x): + return space.wrap(x * 6) + app_g = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'nonnegint']) + w_app_g = space.wrap(app_g) + assert self.space.eq_w(space.call_function(w_app_g, space.wrap(7)), + space.wrap(42)) + assert self.space.eq_w(space.call_function(w_app_g, space.wrap(0)), + space.wrap(0)) + space.raises_w(space.w_ValueError, + space.call_function, w_app_g, space.wrap(-1)) + def test_interp2app_unwrap_spec_args_w(self): space = self.space w = space.wrap From cfbolz at codespeak.net Tue Oct 28 19:20:02 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 28 Oct 2008 19:20:02 +0100 (CET) Subject: [pypy-svn] r59506 - pypy/trunk/lib-python Message-ID: <20081028182002.3B69216A123@codespeak.net> Author: cfbolz Date: Tue Oct 28 19:20:01 2008 New Revision: 59506 Modified: pypy/trunk/lib-python/failure_list.txt Log: done Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Tue Oct 28 19:20:01 2008 @@ -38,7 +38,6 @@ test_float float.__getformat__() exists mainly only for tests test_fork1 ! why did this fail just once? test_format test checking for exact exception messages -test_funcattrs ! easy to add this new attribute test_functools ! missing gc.collect(); some impl details; del p.__dict__? test_gc internal stuff, we may want to provide placeholders test_generators ! I really hate our bytecode compiler :-( From cfbolz at codespeak.net Tue Oct 28 19:20:15 2008 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 28 Oct 2008 19:20:15 +0100 (CET) Subject: [pypy-svn] r59507 - in pypy/trunk/pypy/interpreter: . test Message-ID: <20081028182015.D7B3516A126@codespeak.net> Author: cfbolz Date: Tue Oct 28 19:20:15 2008 New Revision: 59507 Modified: pypy/trunk/pypy/interpreter/nestedscope.py pypy/trunk/pypy/interpreter/test/test_nestedscope.py pypy/trunk/pypy/interpreter/typedef.py Log: implement cell_contents attribute on Cells. Modified: pypy/trunk/pypy/interpreter/nestedscope.py ============================================================================== --- pypy/trunk/pypy/interpreter/nestedscope.py (original) +++ pypy/trunk/pypy/interpreter/nestedscope.py Tue Oct 28 19:20:15 2008 @@ -57,6 +57,13 @@ return "<%s(%s) at 0x%x>" % (self.__class__.__name__, content, uid(self)) + def descr__cell_contents(space, self): + try: + return self.get() + except ValueError: + raise OperationError(space.w_ValueError, space.wrap("Cell is empty")) + + super_initialize_frame_scopes = pyframe.PyFrame.initialize_frame_scopes super_fast2locals = pyframe.PyFrame.fast2locals Modified: pypy/trunk/pypy/interpreter/test/test_nestedscope.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_nestedscope.py (original) +++ pypy/trunk/pypy/interpreter/test/test_nestedscope.py Tue Oct 28 19:20:15 2008 @@ -59,3 +59,23 @@ def test_lambda_in_genexpr(self): assert eval('map(apply, (lambda: t for t in range(10)))') == range(10) + + def test_cell_contents(self): + def f(x): + def f(y): + return x + y + return f + + g = f(10) + assert g.func_closure[0].cell_contents == 10 + + def test_empty_cell_contents(self): + + def f(): + def f(y): + return x + y + return f + x = 1 + + g = f() + raises(ValueError, "g.func_closure[0].cell_contents") Modified: pypy/trunk/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/pypy/interpreter/typedef.py (original) +++ pypy/trunk/pypy/interpreter/typedef.py Tue Oct 28 19:20:15 2008 @@ -877,6 +877,7 @@ unwrap_spec=['self', ObjSpace]), __setstate__ = interp2app(Cell.descr__setstate__, unwrap_spec=['self', ObjSpace, W_Root]), + cell_contents= GetSetProperty(Cell.descr__cell_contents, cls=Cell), ) Cell.acceptable_as_base_class = False From fijal at codespeak.net Tue Oct 28 19:31:09 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 19:31:09 +0100 (CET) Subject: [pypy-svn] r59508 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081028183109.CEC4716A14D@codespeak.net> Author: fijal Date: Tue Oct 28 19:31:06 2008 New Revision: 59508 Added: pypy/trunk/lib-python/modified-2.5.2/test/test_unicode.py - copied, changed from r59478, pypy/trunk/lib-python/2.5.2/test/test_unicode.py Log: relax a bit checks here Copied: pypy/trunk/lib-python/modified-2.5.2/test/test_unicode.py (from r59478, pypy/trunk/lib-python/2.5.2/test/test_unicode.py) ============================================================================== --- pypy/trunk/lib-python/2.5.2/test/test_unicode.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_unicode.py Tue Oct 28 19:31:06 2008 @@ -823,7 +823,7 @@ # to take a 64-bit long, this test should apply to all platforms. if sys.maxint > (1 << 32) or struct.calcsize('P') != 4: return - self.assertRaises(OverflowError, u't\tt\t'.expandtabs, sys.maxint) + self.assertRaises((MemoryError, OverflowError), u't\tt\t'.expandtabs, sys.maxint) def test_main(): From fijal at codespeak.net Tue Oct 28 19:31:47 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 19:31:47 +0100 (CET) Subject: [pypy-svn] r59509 - in pypy/trunk/pypy/module/_socket: . test Message-ID: <20081028183147.4E01116A158@codespeak.net> Author: fijal Date: Tue Oct 28 19:31:46 2008 New Revision: 59509 Modified: pypy/trunk/pypy/module/_socket/interp_socket.py pypy/trunk/pypy/module/_socket/test/test_sock_app.py Log: A test and a fix Modified: pypy/trunk/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/trunk/pypy/module/_socket/interp_socket.py (original) +++ pypy/trunk/pypy/module/_socket/interp_socket.py Tue Oct 28 19:31:46 2008 @@ -1,5 +1,6 @@ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.typedef import TypeDef, make_weakref_descr +from pypy.interpreter.typedef import TypeDef, make_weakref_descr,\ + interp_attrproperty from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped from pypy.interpreter.gateway import interp2app from pypy.rlib.rarithmetic import intmask @@ -187,7 +188,7 @@ except SocketError, e: raise converted_error(space, e) return space.wrap(data) - recv_w.unwrap_spec = ['self', ObjSpace, int, int] + recv_w.unwrap_spec = ['self', ObjSpace, 'nonnegint', int] def recvfrom_w(self, space, buffersize, flags=0): """recvfrom(buffersize[, flags]) -> (data, address info) @@ -203,7 +204,7 @@ return space.newtuple([space.wrap(data), w_addr]) except SocketError, e: raise converted_error(space, e) - recvfrom_w.unwrap_spec = ['self', ObjSpace, int, int] + recvfrom_w.unwrap_spec = ['self', ObjSpace, 'nonnegint', int] def send_w(self, space, data, flags=0): """send(data[, flags]) -> count @@ -472,5 +473,6 @@ [*] not available on all platforms!""", __new__ = descr_socket_new, __weakref__ = make_weakref_descr(W_RSocket), + family = interp_attrproperty('family', W_RSocket), ** socketmethods ) Modified: pypy/trunk/pypy/module/_socket/test/test_sock_app.py ============================================================================== --- pypy/trunk/pypy/module/_socket/test/test_sock_app.py (original) +++ pypy/trunk/pypy/module/_socket/test/test_sock_app.py Tue Oct 28 19:31:46 2008 @@ -538,6 +538,11 @@ msg = buf.tostring()[:len(MSG)] assert msg == MSG + def test_family(self): + import socket + cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + assert cli.family == socket.AF_INET + class AppTestErrno: def setup_class(cls): cls.space = space @@ -556,4 +561,3 @@ assert errno.errorcode[e.args[0]].endswith("EINVAL") assert isinstance(e.args[1], str) - From fijal at codespeak.net Tue Oct 28 21:00:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 21:00:33 +0100 (CET) Subject: [pypy-svn] r59510 - pypy/trunk/lib-python/modified-2.5.2 Message-ID: <20081028200033.3186E16A1FC@codespeak.net> Author: fijal Date: Tue Oct 28 21:00:31 2008 New Revision: 59510 Added: pypy/trunk/lib-python/modified-2.5.2/zipfile.py - copied, changed from r59507, pypy/trunk/lib-python/2.5.2/zipfile.py Log: I *think* struct should rather be string about negative values for unsigned fields. I'm not sure if it's completely fine, but let's fix it for now... Copied: pypy/trunk/lib-python/modified-2.5.2/zipfile.py (from r59507, pypy/trunk/lib-python/2.5.2/zipfile.py) ============================================================================== --- pypy/trunk/lib-python/2.5.2/zipfile.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/zipfile.py Tue Oct 28 21:00:31 2008 @@ -32,9 +32,9 @@ # Other ZIP compression methods not supported # Here are some struct module formats for reading headers -structEndArchive = "<4s4H2LH" # 9 items, end of archive, 22 bytes +structEndArchive = "<4s4H2lH" # 9 items, end of archive, 22 bytes stringEndArchive = "PK\005\006" # magic number for end of archive record -structCentralDir = "<4s4B4HlLL5HLL"# 19 items, central directory, 46 bytes +structCentralDir = "<4s4B4HlLL5HLl"# 19 items, central directory, 46 bytes stringCentralDir = "PK\001\002" # magic number for central directory structFileHeader = "<4s2B4HlLL2H" # 12 items, file header record, 30 bytes stringFileHeader = "PK\003\004" # magic number for file header From fijal at codespeak.net Tue Oct 28 21:04:36 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 21:04:36 +0100 (CET) Subject: [pypy-svn] r59511 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081028200436.2D0AC16A112@codespeak.net> Author: fijal Date: Tue Oct 28 21:04:34 2008 New Revision: 59511 Removed: pypy/trunk/lib-python/modified-2.5.2/test/test_zipimport.py Log: original test is better now From fijal at codespeak.net Tue Oct 28 21:19:55 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 28 Oct 2008 21:19:55 +0100 (CET) Subject: [pypy-svn] r59512 - in pypy/trunk/pypy/module/zipimport: . test Message-ID: <20081028201955.6389416A248@codespeak.net> Author: fijal Date: Tue Oct 28 21:19:53 2008 New Revision: 59512 Modified: pypy/trunk/pypy/module/zipimport/interp_zipimport.py pypy/trunk/pypy/module/zipimport/test/test_zipimport.py Log: A test and a fix. Also simplify handling of modules a bit Modified: pypy/trunk/pypy/module/zipimport/interp_zipimport.py ============================================================================== --- pypy/trunk/pypy/module/zipimport/interp_zipimport.py (original) +++ pypy/trunk/pypy/module/zipimport/interp_zipimport.py Tue Oct 28 21:19:53 2008 @@ -282,11 +282,16 @@ def get_source(self, space, fullname): filename = self.mangle(fullname) + found = False for compiled, _, ext in ENUMERATE_EXTS: - if not compiled: - fname = filename + ext - if self.have_modulefile(space, fname): + fname = filename + ext + if self.have_modulefile(space, fname): + if not compiled: return self.get_data(space, fname) + else: + found = True + if found: + return space.w_None raise OperationError(self.w_ZipImportError, space.wrap( "Cannot find source for %s in %s" % (filename, self.name))) get_source.unwrap_spec = ['self', ObjSpace, str] Modified: pypy/trunk/pypy/module/zipimport/test/test_zipimport.py ============================================================================== --- pypy/trunk/pypy/module/zipimport/test/test_zipimport.py (original) +++ pypy/trunk/pypy/module/zipimport/test/test_zipimport.py Tue Oct 28 21:19:53 2008 @@ -84,6 +84,8 @@ w_cache = space.getattr(space.getbuiltinmodule('zipimport'), space.wrap('_zip_directory_cache')) space.call_function(space.getattr(w_cache, space.wrap('clear'))) + self.w_modules = space.getattr(space.getbuiltinmodule('sys'), + space.wrap('modules')) def teardown_method(self, meth): space = self.space @@ -92,6 +94,8 @@ while sys.path[0].endswith('.zip'): sys.path.pop(0) """) + space.setattr(space.getbuiltinmodule('sys'), + space.wrap('modules'), self.w_modules) def test_cache(self): self.writefile(self, 'x.py', 'y') @@ -130,7 +134,6 @@ for key, val in expected.items(): assert mod.__dict__[key] == val assert mod.__file__.endswith('.zip'+os.sep+'uuu.py') - del sys.modules['uuu'] def test_pyc(self): import sys, os @@ -148,7 +151,6 @@ assert mod.__file__.endswith('.zip'+os.sep+'uuu.pyc') assert mod.get_file() == mod.__file__ assert mod.get_name() == mod.__name__ - del sys.modules['uuu'] def test_bad_pyc(self): import zipimport @@ -169,7 +171,6 @@ self.writefile(self, "uu.py", "def f(x): return x") mod = __import__("uu", globals(), locals(), []) assert mod.f(3) == 3 - del sys.modules['uu'] def test_sys_modules(self): m0 = ord(self.test_pyc[0]) @@ -182,7 +183,6 @@ sys.modules['uuu'] = lambda x : x + 1 mod = z.load_module('uuu') assert mod(3) == 4 - del sys.modules['uuu'] def test_package(self): import os, sys @@ -191,8 +191,6 @@ mod = __import__("xxuuu", globals(), locals(), ['yy']) assert mod.__path__ assert mod.yy.f(3) == 3 - del sys.modules['xxuuu'] - del sys.modules['xxuuu.yy'] def test_functions(self): import os @@ -207,6 +205,7 @@ assert z.is_package("xx") assert not z.is_package("yy") assert z.get_source("yy") == '3' + assert z.get_source('uu') is None raises(ImportError, "z.get_source('zz')") #assert z.get_code('yy') == py.code.Source('3').compile() #assert z.get_code('uu') == self.co From antocuni at codespeak.net Wed Oct 29 13:42:38 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 29 Oct 2008 13:42:38 +0100 (CET) Subject: [pypy-svn] r59517 - in pypy/branch/oo-jit/pypy: annotation jit/rainbow rpython/ootypesystem Message-ID: <20081029124238.275F216A1DB@codespeak.net> Author: antocuni Date: Wed Oct 29 13:42:36 2008 New Revision: 59517 Modified: pypy/branch/oo-jit/pypy/annotation/unaryop.py pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py pypy/branch/oo-jit/pypy/rpython/ootypesystem/rootype.py Log: some rpython fixes, and add support for reading __class__ on a SomeOOInstance; I'm not really sure that this is the way to go, but seems to work. test_promote_class still fail, probably because of some other bug. Modified: pypy/branch/oo-jit/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/oo-jit/pypy/annotation/unaryop.py (original) +++ pypy/branch/oo-jit/pypy/annotation/unaryop.py Wed Oct 29 13:42:36 2008 @@ -658,6 +658,7 @@ # annotation of low-level types from pypy.annotation.model import SomePtr, SomeLLADTMeth from pypy.annotation.model import SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth +from pypy.annotation.model import SomeOOClass from pypy.annotation.model import ll_to_annotation, lltype_to_annotation, annotation_to_lltype class __extend__(SomePtr): @@ -704,7 +705,10 @@ from pypy.rpython.ootypesystem import ootype class __extend__(SomeOOInstance): def getattr(r, s_attr): + from pypy.rpython.ootypesystem.rclass import CLASSTYPE assert s_attr.is_constant(), "getattr on ref %r with non-constant field-name" % r.ootype + if s_attr.const == '__class__': + return SomeOOInstance(CLASSTYPE) v = getattr(r.ootype._example(), s_attr.const) if isinstance(v, ootype._bound_meth): return SomeOOBoundMeth(r.ootype, s_attr.const) Modified: pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py Wed Oct 29 13:42:36 2008 @@ -632,13 +632,14 @@ @arguments("red", "green", "fielddesc", "fielddesc", returns="red") def opimpl_assert_class(self, objbox, gv_class, fielddesc, fielddesc2): + assert isinstance(objbox, rvalue.AbstractPtrRedBox) if isinstance(objbox.content, rcontainer.VirtualStruct): return objbox classbox = self.PtrRedBox(gv_class) objbox.remember_field(fielddesc, classbox) # hack hack, see comments in codewriter.py - if fielddesc2 != fielddesc: + if fielddesc2 is not fielddesc: objbox.remember_field(fielddesc2, classbox) return objbox Modified: pypy/branch/oo-jit/pypy/rpython/ootypesystem/rootype.py ============================================================================== --- pypy/branch/oo-jit/pypy/rpython/ootypesystem/rootype.py (original) +++ pypy/branch/oo-jit/pypy/rpython/ootypesystem/rootype.py Wed Oct 29 13:42:36 2008 @@ -54,12 +54,21 @@ self.lowleveltype = ootype def rtype_getattr(self, hop): + from pypy.rpython.ootypesystem.rclass import CLASSTYPE attr = hop.args_s[1].const s_inst = hop.args_s[0] _, meth = self.lowleveltype._lookup(attr) if meth is not None: # just return instance - will be handled by simple_call return hop.inputarg(hop.r_result, arg=0) + if attr == '__class__': + v_inst = hop.inputarg(hop.args_r[0], arg=0) + # this will work as soon as we merge the less-meta-instances branch + #return hop.genop('classof', [v_obj], resulttype = hop.r_result.lowleveltype) + cmeta = hop.inputconst(ootype.Void, "meta") + return hop.genop('oogetfield', [v_inst, cmeta], + resulttype=CLASSTYPE) + self.lowleveltype._check_field(attr) vlist = hop.inputargs(self, Void) return hop.genop("oogetfield", vlist, From fijal at codespeak.net Wed Oct 29 16:02:20 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 29 Oct 2008 16:02:20 +0100 (CET) Subject: [pypy-svn] r59519 - in pypy/build/benchmem: . testing Message-ID: <20081029150220.A983116A0D7@codespeak.net> Author: fijal Date: Wed Oct 29 16:02:18 2008 New Revision: 59519 Added: pypy/build/benchmem/testing/test_tracing.py (contents, props changed) pypy/build/benchmem/tracer.py (contents, props changed) Log: Support for tracing Added: pypy/build/benchmem/testing/test_tracing.py ============================================================================== --- (empty file) +++ pypy/build/benchmem/testing/test_tracing.py Wed Oct 29 16:02:18 2008 @@ -0,0 +1,31 @@ + +from tracer import run_with_tracing, trace_in_another_process +import py + +def test_base_tracing(): + def g(): + pass + + def f(): + for i in range(100): + g() + + l = [] + results = run_with_tracing(f, lambda : l.append('line')) + assert len(l) == 503 + +def test_tracing_in_other_process(): + tmpdir = py.test.ensuretemp('tracing_in_other_process') + filename = tmpdir.join('somefile.py') + source = py.code.Source(""" + def g(): + pass + + def f(): + for i in range(100): + g() + """) + l = [] + trace_in_another_process(filename, source, 'f', lambda : l.append(None)) + assert len(l) == 503 + Added: pypy/build/benchmem/tracer.py ============================================================================== --- (empty file) +++ pypy/build/benchmem/tracer.py Wed Oct 29 16:02:18 2008 @@ -0,0 +1,44 @@ + +import sys, py, os + +def wrapper(func_to_run): + def f(frame, event, arg): + func_to_run() + return f + return f + +def run_with_tracing(f, func_to_run): + sys.settrace(wrapper(func_to_run)) + f() + sys.settrace(None) + +def trace_in_another_process(filename, source_code, func_name, measure_func): + source = py.code.Source(source_code, """ + import sys + sys.path.insert(0, '%s') + from tracer import run_with_tracing + + def write(): + sys.stdout.write('c') + sys.stdout.flush() + sys.stdin.read(1) + + if __name__ == '__main__': + run_with_tracing(%s, write) + sys.stdout.write('F') + sys.stdout.flush() + """ % (py.magic.autopath().dirpath(), func_name)) + + f = py.path.local(filename) + f.write(source) + cmd = "%s -u %s" % (sys.executable, f) + stdout, stdin = os.popen2(cmd) + while 1: + ch = stdin.read(1) + if ch == 'F': + break + assert ch == 'c' + stdout.write('c') + stdout.flush() + measure_func() + From arigo at codespeak.net Wed Oct 29 16:46:27 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 29 Oct 2008 16:46:27 +0100 (CET) Subject: [pypy-svn] r59521 - pypy/trunk/lib-python Message-ID: <20081029154627.71E5516A182@codespeak.net> Author: arigo Date: Wed Oct 29 16:46:25 2008 New Revision: 59521 Modified: pypy/trunk/lib-python/failure_list.txt Log: test_tuple indeed passes for me. Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Wed Oct 29 16:46:25 2008 @@ -96,7 +96,6 @@ test_timeout skipped test test_trace probably all acceptable differences test_traceback ! don't care about '__members__', but check the other tests -test_tuple ! might be fixed now, check again test_unicode ! some failures, look deeper test_unicode_file skipped test test_unicodedata unknown to me (but xorAxAx and fijal have a better clue) From fijal at codespeak.net Wed Oct 29 16:53:06 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 29 Oct 2008 16:53:06 +0100 (CET) Subject: [pypy-svn] r59522 - in pypy/build/benchmem: . testing Message-ID: <20081029155306.7152816A1C4@codespeak.net> Author: fijal Date: Wed Oct 29 16:53:05 2008 New Revision: 59522 Modified: pypy/build/benchmem/runbench.py pypy/build/benchmem/testing/test_benchtool.py pypy/build/benchmem/testing/test_tracing.py pypy/build/benchmem/tracer.py Log: Some support for measurments of perceived pauses Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Wed Oct 29 16:53:05 2008 @@ -11,6 +11,7 @@ import py import smaps +import time optparse = py.compat.optparse mydir = py.magic.autopath().dirpath() @@ -37,6 +38,15 @@ l.sort() return l + def write_benchheader(self, benchname, args): + print >>self.logstream, self.SEPBENCH + print >>self.logstream, "#benchtype=%s" % (self.benchtype,) + print >>self.logstream, "#executable=%s" %(str(self.executable ),) + print >>self.logstream, "#benchpath=%s" %(self.benchpath.basename,) + print >>self.logstream, "#benchname=%s" %(benchname,) + print >>self.logstream, "#benchargs=%s" %(args,) + print >>self.logstream + def log(self, *args): print " ".join(map(str, args)) @@ -104,6 +114,8 @@ class BenchRunnerObjsize(BenchRunner): + benchtype = 'objsizes' + def __init__(self, executable, logpath, options): BenchRunner.__init__(self, executable, logpath, options) self.benchpath = benchmarkdir.join("sizes.py") @@ -137,15 +149,6 @@ p.write(source) return p - def write_benchheader(self, benchname, args): - print >>self.logstream, self.SEPBENCH - print >>self.logstream, "#benchtype=objsizes" - print >>self.logstream, "#executable=%s" %(str(self.executable ),) - print >>self.logstream, "#benchpath=%s" %(self.benchpath.basename,) - print >>self.logstream, "#benchname=%s" %(benchname,) - print >>self.logstream, "#benchargs=%s" %(args,) - print >>self.logstream - def run(self): for name in self.getnames(): self.run_checkpointed(name) @@ -179,20 +182,12 @@ class BenchRunnerAppProfiles(BenchRunner): ITER2 = 10 + benchtype = 'appprofiles' def __init__(self, *args): BenchRunner.__init__(self, *args) self.benchpath = benchmarkdir.join("appprofiles.py") - def write_benchheader(self, benchname, args): - print >>self.logstream, self.SEPBENCH - print >>self.logstream, "#benchtype=appprofiles" - print >>self.logstream, "#executable=%s" %(str(self.executable ),) - print >>self.logstream, "#benchpath=%s" %(self.benchpath.basename,) - print >>self.logstream, "#benchname=%s" %(benchname,) - print >>self.logstream, "#benchargs=%s" %(args,) - print >>self.logstream - def run(self): for name in self.getnames(): self.run_once(name) @@ -234,6 +229,40 @@ except py.error.ENOENT: break +class BenchRunnerPauses(BenchRunner): + benchtype = 'pauses' + + def __init__(self, *args): + BenchRunner.__init__(self, *args) + self.benchpath = benchmarkdir.join("appprofiles.py") + self.last_t = time.time() + # XXX + self.args = (1000, 3) + + def run(self): + for name in self.getnames(): + self.run_once(name) + + def write_header(self): + self.write_benchheader('pauses', self.args) + + def write_footer(self): + pass + + def measure(self): + t = time.time() + diff = t - self.last_t + self.logstream.write(str(diff) + "\n") + self.last_t = t + + def run_once(self, name): + self.write_header() + from tracer import trace_in_another_process + trace_in_another_process(self.tmpdir.join(self.benchpath.basename), + self.benchpath.read(), + name, self.measure, self.executable, + self.args) + self.write_footer() # # ================ reading a benchmark log file ======================= @@ -291,7 +320,8 @@ yield parse_result(stream_iter, kw, private_only) def parse_result(stream, kw, private_only): - chosen_cls = benchtype2class[kw.pop('benchtype')] + benchtype = kw.pop('benchtype') + chosen_cls = benchtype2class[benchtype] return chosen_cls.parse(stream, kw, private_only) class Result(object): @@ -372,6 +402,23 @@ timings.append((name, times)) return cls(timings, **kw) +class PausesResult(Result): + benchtype = 'pauses' + + def __init__(self, lst, **kw): + for k, v in kw.items(): + setattr(self, k, v) + self.lst = lst + + @classmethod + def parse(cls, lnstream, kw, private_only=False): + lst = [] + for lineno, line in lnstream: + if line.strip() == BenchRunner.SEPBENCH: + break + lst.append(float(line)) + return cls(lst, **kw) + benchtype2class = {} def _update_benchtyp2class(): @@ -475,6 +522,8 @@ return BenchRunnerBaseTime elif benchtype == "appprofiles": return BenchRunnerAppProfiles + elif benchtype == 'pauses': + xxx else: raise NotImplementedError("Benchmark type: %s" % (benchtype,)) Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Wed Oct 29 16:53:05 2008 @@ -59,6 +59,21 @@ assert len(results) == 1 assert len(results[0].snapshots) +def test_pauses(): + tmpdir = py.test.ensuretemp("benchrunner") + benchlog=tmpdir.join("log_pauses") + + class options: + numiter = 10 + runner = runbench.BenchRunnerPauses("python2.5", benchlog, options) + assert runner.benchpath.basename == "appprofiles.py" + runner.run() + resultset = runbench.ResultSet() + resultset.parse(benchlog) + for name, results in resultset.getname2results(): + assert len(results) == 4 + assert len(results[0].lst) + def test_runbench_functional(): script = py.path.local(runbench.__file__).dirpath("runbench.py") output = py.process.cmdexec("python %s --numiter=10" %(script)) Modified: pypy/build/benchmem/testing/test_tracing.py ============================================================================== --- pypy/build/benchmem/testing/test_tracing.py (original) +++ pypy/build/benchmem/testing/test_tracing.py Wed Oct 29 16:53:05 2008 @@ -1,6 +1,6 @@ from tracer import run_with_tracing, trace_in_another_process -import py +import py, sys def test_base_tracing(): def g(): @@ -26,6 +26,7 @@ g() """) l = [] - trace_in_another_process(filename, source, 'f', lambda : l.append(None)) + trace_in_another_process(filename, source, 'f', lambda : l.append(None), + sys.executable) assert len(l) == 503 Modified: pypy/build/benchmem/tracer.py ============================================================================== --- pypy/build/benchmem/tracer.py (original) +++ pypy/build/benchmem/tracer.py Wed Oct 29 16:53:05 2008 @@ -7,12 +7,13 @@ return f return f -def run_with_tracing(f, func_to_run): +def run_with_tracing(f, func_to_run, args=()): sys.settrace(wrapper(func_to_run)) - f() + f(*args) sys.settrace(None) -def trace_in_another_process(filename, source_code, func_name, measure_func): +def trace_in_another_process(filename, source_code, func_name, measure_func, + executable, args=()): source = py.code.Source(source_code, """ import sys sys.path.insert(0, '%s') @@ -24,14 +25,14 @@ sys.stdin.read(1) if __name__ == '__main__': - run_with_tracing(%s, write) + run_with_tracing(%s, write, %s) sys.stdout.write('F') sys.stdout.flush() - """ % (py.magic.autopath().dirpath(), func_name)) + """ % (py.magic.autopath().dirpath(), func_name, args)) f = py.path.local(filename) f.write(source) - cmd = "%s -u %s" % (sys.executable, f) + cmd = "%s -u %s" % (executable, f) stdout, stdin = os.popen2(cmd) while 1: ch = stdin.read(1) From arigo at codespeak.net Wed Oct 29 17:08:43 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 29 Oct 2008 17:08:43 +0100 (CET) Subject: [pypy-svn] r59524 - in pypy/trunk/pypy/interpreter: . test Message-ID: <20081029160843.D3C6616A141@codespeak.net> Author: arigo Date: Wed Oct 29 17:08:43 2008 New Revision: 59524 Modified: pypy/trunk/pypy/interpreter/test/test_function.py pypy/trunk/pypy/interpreter/typedef.py Log: Oups. Code without test is bound to not work... Modified: pypy/trunk/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_function.py (original) +++ pypy/trunk/pypy/interpreter/test/test_function.py Wed Oct 29 17:08:43 2008 @@ -203,6 +203,13 @@ assert f.__doc__ == u"hi" assert type(f.__doc__) is unicode + def test_subclassing(self): + # cannot subclass 'function' or 'builtin_function' + def f(): + pass + raises(TypeError, type, 'Foo', (type(f),), {}) + raises(TypeError, type, 'Foo', (type(len),), {}) + class AppTestMethod: def test_simple_call(self): class A(object): @@ -542,6 +549,3 @@ """) assert space.is_true(w_res) - - - Modified: pypy/trunk/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/pypy/interpreter/typedef.py (original) +++ pypy/trunk/pypy/interpreter/typedef.py Wed Oct 29 17:08:43 2008 @@ -134,6 +134,7 @@ def get_unique_interplevel_subclass(cls, hasdict, wants_slots, needsdel=False, weakrefable=False): "NOT_RPYTHON: initialization-time only" + assert cls.typedef.acceptable_as_base_class key = cls, hasdict, wants_slots, needsdel, weakrefable try: return _subclass_cache[key] @@ -499,7 +500,7 @@ __objclass__ = GetSetProperty(GetSetProperty.descr_get_objclass), __doc__ = interp_attrproperty('doc', cls=GetSetProperty), ) -GetSetProperty.acceptable_as_base_class = False +GetSetProperty.typedef.acceptable_as_base_class = False class Member(Wrappable): @@ -560,7 +561,7 @@ __name__ = interp_attrproperty('name', cls=Member), __objclass__ = interp_attrproperty_w('w_cls', cls=Member), ) -Member.acceptable_as_base_class = False +Member.typedef.acceptable_as_base_class = False # ____________________________________________________________ # @@ -651,14 +652,14 @@ co_flags = GetSetProperty(fget_co_flags, cls=Code), co_consts = GetSetProperty(fget_co_consts, cls=Code), ) -Code.acceptable_as_base_class = False +Code.typedef.acceptable_as_base_class = False Frame.typedef = TypeDef('internal-frame', f_code = GetSetProperty(Frame.fget_code), f_locals = GetSetProperty(Frame.fget_getdictscope), f_globals = interp_attrproperty_w('w_globals', cls=Frame), ) -Frame.acceptable_as_base_class = False +Frame.typedef.acceptable_as_base_class = False PyCode.typedef = TypeDef('code', __new__ = interp2app(PyCode.descr_code__new__.im_func), @@ -683,7 +684,7 @@ co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), co_lnotab = interp_attrproperty('co_lnotab', cls=PyCode), ) -PyCode.acceptable_as_base_class = False +PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', __reduce__ = interp2app(PyFrame.descr__reduce__, @@ -701,7 +702,7 @@ f_exc_traceback = GetSetProperty(PyFrame.fget_f_exc_traceback), f_restricted = GetSetProperty(PyFrame.fget_f_restricted), **Frame.typedef.rawdict) -PyFrame.acceptable_as_base_class = False +PyFrame.typedef.acceptable_as_base_class = False Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func, @@ -762,7 +763,7 @@ __module__ = getset___module__, __weakref__ = make_weakref_descr(Function), ) -Function.acceptable_as_base_class = False +Function.typedef.acceptable_as_base_class = False Method.typedef = TypeDef("method", __new__ = interp2app(Method.descr_method__new__.im_func), @@ -781,7 +782,7 @@ unwrap_spec=['self', ObjSpace]), __weakref__ = make_weakref_descr(Method), ) -Method.acceptable_as_base_class = False +Method.typedef.acceptable_as_base_class = False StaticMethod.typedef = TypeDef("staticmethod", __doc__ = """staticmethod(function) -> static method @@ -835,7 +836,7 @@ '__repr__': interp2app(BuiltinFunction.descr_function_repr), }) del BuiltinFunction.typedef.rawdict['__get__'] -BuiltinFunction.acceptable_as_base_class = False +BuiltinFunction.typedef.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", __reduce__ = interp2app(PyTraceback.descr__reduce__, @@ -847,7 +848,7 @@ tb_lineno = interp_attrproperty('lineno', cls=PyTraceback), tb_next = interp_attrproperty('next', cls=PyTraceback), ) -PyTraceback.acceptable_as_base_class = False +PyTraceback.typedef.acceptable_as_base_class = False GeneratorIterator.typedef = TypeDef("generator", __reduce__ = interp2app(GeneratorIterator.descr__reduce__, @@ -866,7 +867,7 @@ gi_frame = interp_attrproperty('frame', cls=GeneratorIterator), __weakref__ = make_weakref_descr(GeneratorIterator), ) -GeneratorIterator.acceptable_as_base_class = False +GeneratorIterator.typedef.acceptable_as_base_class = False Cell.typedef = TypeDef("cell", __eq__ = interp2app(Cell.descr__eq__, @@ -879,20 +880,20 @@ unwrap_spec=['self', ObjSpace, W_Root]), cell_contents= GetSetProperty(Cell.descr__cell_contents, cls=Cell), ) -Cell.acceptable_as_base_class = False +Cell.typedef.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", __repr__ = interp2app(Ellipsis.descr__repr__), ) -Ellipsis.acceptable_as_base_class = False +Ellipsis.typedef.acceptable_as_base_class = False NotImplemented.typedef = TypeDef("NotImplemented", __repr__ = interp2app(NotImplemented.descr__repr__), ) -NotImplemented.acceptable_as_base_class = False +NotImplemented.typedef.acceptable_as_base_class = False SuspendedUnroller.typedef = TypeDef("SuspendedUnroller") -SuspendedUnroller.acceptable_as_base_class = False +SuspendedUnroller.typedef.acceptable_as_base_class = False interptypes = [ val.typedef for name,val in globals().items() if hasattr(val,'__bases__') and hasattr(val,'typedef') ] From hpk at codespeak.net Thu Oct 30 05:58:39 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 30 Oct 2008 05:58:39 +0100 (CET) Subject: [pypy-svn] r59528 - pypy/trunk/pypy/doc Message-ID: <20081030045839.9F50C16A098@codespeak.net> Author: hpk Date: Thu Oct 30 05:58:36 2008 New Revision: 59528 Modified: pypy/trunk/pypy/doc/maemo.txt Log: review, test and partially simplify and rewrite instructions. assume a reader that don't much about maemo/scratchbox and pypy installation. hope i got everything correct together. the maemo-sdk install script actually installs two very large targets whereas one usually only needs one. bit of a bummer. Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Thu Oct 30 05:58:36 2008 @@ -1,282 +1,169 @@ How to run PyPy on top of maemo platform ======================================== -XXX this document needs cleanup, contains duplicate information, will need cleanup - after experiments yielded the best way to do pypy-c translations. +This howto explains how to use Scratchbox_ to cross-compile PyPy's +Python Interpreter to an `Internet-Tablet-OS`_, more specifically +the Maemo_ platform. This howto should work well for getting +a usable Python Interpreter for Nokia's N810_ device. + +.. _N810: http://en.wikipedia.org/wiki/Nokia_N810 +.. _`Internet-Tabel-OS`: _http://en.wikipedia.org/wiki/Internet_Tablet_OS +.. _Maemo: http://www.maemo.org +.. _Scratchbox: http://www.scratchbox.org +.. _`INSTALL.txt`: http://tablets-dev.nokia.com/4.1/INSTALL.txt + +setup cross-compilation environment +------------------------------------- + +The main steps are to install scratchbox and the Maemo SDK. Most of the +information from this section is taken from Nokia's `INSTALL.txt`_ which +provides more detail. + +Adjust linux kernel settings ++++++++++++++++++++++++++++++++++ + +In order to install and run scratchbox you will need to adjust +your Linux kernel settings. Note that the VDSO setting may +crash your computer - if that is the case, try running without +this setting. -This is a short introduction that explains how to obtain a cross-compiled binary -of PyPy for the Maemo platform. + $ echo 4096 | sudo tee /proc/sys/vm/mmap_min_addr + $ echo 0 | sudo tee /proc/sys/vm/vdso_enabled -Cross compilation means that a certain environment will produce an -executable binary which can then be copied to the target environment -and be run without any dependency problems. -In order to provide a usable cross compilation framework for PyPy, -Scratchbox and the Maemo SDK are required. While the former provides -a framework for reproducibly building software packages through -the definition of target profiles and so called devkits, the latter -one provides a set of targets and rootstraps for the compilation -of applications that work on Maemo powered devices. +If that works fine for you (on some machines the vdso setting can freeze machines) +you can make the changes permanent by editing ``/etc/sysctl.conf`` to contain:: -The Maemo SDK can be downloaded on http://maemo.org/development/sdks/ -You can find all relevant downloads on the referenced pages. - -Before you can start the installation, you need to decide which Maemo -version you need. This mostly depends on the installed version on the -device. We assume that you are running Maemo 4.1. URLs referring to files -in this document will therefore hardcode this version. Just as an example, -the Nokia n810 is shipped with a Maemo 4.0 installation, so 4.1 will not fit. - -In order to get a working SDK environment, you need the file -INSTALL.txt which explains the installation of the Maemo -development environment. You can find the one for Maemo 4.1 here: -http://tablets-dev.nokia.com/4.1/INSTALL.txt - -This document only refers to sections in INSTALL.txt but does not reproduce -all details. + vm.vdso_enabled = 0 + vm.mmap_min_addr = 4096 +install scratchbox packages ++++++++++++++++++++++++++++++++++ -Doing it sanely ------------------------------------ +Download -Installing Scratchbox -+++++++++++++++++++++ + http://repository.maemo.org/stable/diablo/maemo-scratchbox-install_4.1.1.sh -First of all, Scratchbox needs to be installed. This is done as ``root``. -The installation can be done using an installer script, packages supplied -by the particular linux distribution or manually. Details can be found in section 1 -of the file INSTALL.txt. The URL of the installer is:: +and run this script as root:: - http://tablets-dev.nokia.com/4.1/maemo-scratchbox-install_4.1.sh + $ sh maemo-scratchbox-install_4.1.1.sh -u ACCOUNTNAME -The script will automatically select the necessary devkits and toolchains -and even automatically use Debian packages on Debian based machines. +The script will automatically download Debian packages or tarballs +and pre-configure a scratchbox environment with so called "devkits" +and "toolchains" for performing cross-compilation. -Additional important steps include fixing the mmap and vdso settings -of the kernel (cf. section 1.3), -and the addition of your user account to a special group -(by supplying ``-u YOURUSERNAME`` to the installation script). +It also sets up an "sbox" group on your system and makes the +the user "ACCOUNTNAME" a member of that group. Members of the group +have the right to log into a scratchbox environment. -Note that the usage of the Debian devkits and related manually -engineered target profiles is neither sufficient nor useful to provide -applications for Maemo based devices compared to using the automatic -target profile setup provided by the Maemo SDK. Therefore it is -necessary to also install the Maemo SDK as explained next. +testing that scratchbox environment works ++++++++++++++++++++++++++++++++++++++++++++++++ +Login freshly to your Linux account in order to activate +your membership in the "sbox" unix group and then type:: -Installing the Maemo SDK -++++++++++++++++++++++++ + $ /scratchbox/login -Afterwards, the Maemo SDK needs to be installed. This is done as a -normal system user (the one that you added to the ``sbox`` group -explained above). One obvious result is that every system user -has his own set of Scratchbox targets. +This should warn you with something like "sb-conf: no current +target" because we have not yet created a cross-compilation +target. -It is strongly recommended to do the installation by executing the -script as explained in section 2.1. The URL of the script is:: +Note that Scratchbox starts services in the background +which can be started and stopped via:: - http://tablets-dev.nokia.com/4.1/maemo-sdk-install_4.1.sh + /scratchbox/sbin/sbox_ctl start|stop -It is useful to select the debug packages when being asked (this is -the default). Closed source nokia binaries are not necessary. -The SDK installation will create two new targets and preselect -the target for ARM compilation. This nearly results in a scratchbox environment -that is usable for cross compilation of PyPy. +Installing the Maemo SDK ++++++++++++++++++++++++++++++++ -The remaining parts of INSTALL.txt describe closed source binaries -and X11 support, we do not need those. +To mimick the specific N810_ environment we now install the Maemo-SDK. +This will create an target within our new scratchbox environment +that we then use to compile PyPy. +Make sure that you are a member of the "sbox" group - this might +require logging out and in again. -Customizing the default targets for PyPy -++++++++++++++++++++++++++++++++++++++++ +Then, download -As PyPy does not yet provide a debian package description -file for use on Maemo, we have to install the dependencies manually -in our Scratchbox. The following steps are necessary to accomplish this: + http://repository.maemo.org/stable/diablo/maemo-sdk-install_4.1.1.sh -1. Go into your scratchbox by executing ``/scratchbox/login`` +and execute it with user priviliges:: -1. Add these lines to ``/etc/apt/sources.list`` and replace DIST - by the appropriate name of your Maemo version (chinook or diablo):: + $ sh maemo-sdk-install_4.1.1.sh - deb http://repository.maemo.org/extras/ DIST free non-free - deb http://repository.maemo.org/extras-devel/ DIST free non-free +When being asked select the default "Runtime + Dev" packages. You do not need +Closed source Nokia binaries for PyPy. This installation +script will download "rootstraps" and create so called +"targets" and preselect the "DIABLO_ARMEL" target for ARM_ +compilation. Within the targets a large number of packages +will be pre-installed resulting in a base scratchbox +environment that is usable for cross compilation of PyPy. -1. Install these packages to gain full support for extension modules:: +Customizing the DIABLO_ARMEL target for PyPy +++++++++++++++++++++++++++++++++++++++++++++++++ - python2.5-dev libffi4-dev zlib1g-dev libbz2-dev libgc-dev libncurses5-dev - - This can be done by running ``apt-get update`` and ``apt-get install`` - accordingly. The latter is only needed if you decide to use the Boehm - garbage collector (in fact, it is only available starting from Diablo). +As PyPy does not yet provide a debian package description +file for use on Maemo, we have to install some dependencies manually +into our Scratchbox target environment. -1. Leave the scratchbox shell again. +1. Go into your scratchbox by executing ``/scratchbox/login`` + (this should bring you to a shell with the DIABLO_ARMEL target) +2. Add these lines to ``/etc/apt/sources.list`` -Translating PyPy for the Maemo platform -+++++++++++++++++++++++++++++++++++++++ + deb http://repository.maemo.org/extras/ diablo free non-free + deb http://repository.maemo.org/extras-devel/ diablo free non-free -Afterwards, you are ready for the translation of RPython programs. -Like in a normal PyPy translation run, your Python interpreter on -the hosting operation system runs the translator. And the translator -itself uses the Scratchbox environment to obtain native target -binaries. This is achieved by running -the following command line in the ``pypy/translator/goal`` directory:: +3. Perform ``apt-get update``. - python translate.py --platform=maemo --opt=mem +4. Install some neccessary packages:: -XXX IMO this needs either a) cleaner explanation b) a script that does that -XXX [creates correct directory to be copied]. "Together with correct path -XXX sounds a bit vague [fijal] -- Yes, a kind of "install" script, -XXX which is, like the inherent problem, completely platform invariant. -XXX -- xoraxax :-) + apt-get install python2.5-dev libffi4-dev zlib1g-dev libbz2-dev libgc-dev libncurses5-dev -When this step is finished, the ``goal`` directory will contain a binary called -``pypy-c`` which is runnable on the Maemo device. Copy the working directory -of PyPy over to your device. In the directory tree, you only need the newly built file -``pypy/translator/goal/pypy-c`` together with ``lib-python`` and the ``pypy/lib`` directory. -Other files and directories are not necessary. -Finally, you can start it on your Maemo device. + The "libgc-dev" package is only needed if you want to use the Boehm + garbage collector. +5. Leave the scratchbox shell again with ``exit``. -Variant 0: manual scratchbox +Translating PyPy for the Maemo platform ------------------------------------------ -The stuff below here can be removed in my opinion. -- xoraxax - - -Installing scratchbox -+++++++++++++++++++++++++++++++++++++++++ - -The basic idea is to follow - - http://www.scratchbox.org/documentation/user/scratchbox-1.0/html/tutorial.htm# - -with tarballs that work for the N810/Maemo target. - -make yourself an empty ``work`` directory and get a -working set of tarballs, e.g. like this:: - - export GET='wget -c' - export URL='http://www.scratchbox.org/download/files/sbox-releases/apophis/tarball' - $GET $URL/scratchbox-core-1.0.11-i386.tar.gz - $GET $URL/scratchbox-libs-1.0.11-i386.tar.gz - $GET $URL/scratchbox-toolchain-cs2007q3-glibc2.5-arm7-1.0.8-6-i386.tar.gz - $GET $URL/scratchbox-devkit-cputransp-1.0.7-i386.tar.gz - $GET $URL/scratchbox-devkit-perl-1.0.4-i386.tar.gz # for autoconf - $GET $URL/scratchbox-devkit-svn-1.0-i386.tar.gz # for being able to checkout - #$GET $URL/scratchbox-devkit-debian-1.0.10-i386.tar.gz # to eventually get debian working - -unpack all those tarballs, e.g. like this:: - - for x in *.tar.gz ; do sudo tar zxvf $x; done - -now you should have a ``work/scratchbox`` directory containing your basic uninitialized -scratchbox environment. - -make a symlink to have scratchbox at the canonical location:: - - ln -s /path/to/work/sandbox /sandbox - -initilaize the scratchbox install (you should be fine with using default answers to any questions):: - - /scratchbox/run_me_first.sh +You at least need "gcc" and "libc-dev" packages on your host system +to compile pypy. The scratchbox and its DIABLO_ARMEL target contains +its own copies of GCC, various C libraries and header files +which pypy needs for successful cross-compilation. -NOTE, that this will implicitely start some services that generally are controlled via:: +Now perform a subversion checkout of PyPy:: - /scratchbox/sbin/sbox_ctrl stop|start + svn co https://codespeak.net/svn/pypy/trunk pypy-trunk -So if you later want to play with multiple different scratchbox installations you should stop the services before moving them away. You can also try to link this script into your ``/etc/init.d/`` so that it automatically runs after a reboot. +Change to the ``pypy-trunk/pypy/translator/goal`` directory and execute:: -Now create a user:: + python translate.py --platform=maemo --opt=mem - /scratchbox/sbin/sbox_adduser USER yes +This will last a some 30-60 minutes on most machines. For compiling +the C source code PyPy's tool chain will use our scratchbox/Maemo +cross-compilation environment. -the 'yes' means that the USER gets added to the sbox unix group, neccessary to login into the virtual environment. -the 'yes' means that the USER gets added to the sbox unix group, neccessary to login into the virtual environment. +When this step succeeds, your ``goal`` directory will contain a binary called +``pypy-c`` which is executable on the Maemo device. To run this binary +on your device you need to also copy some support files. A good way to +perform copies to your device is to install OpenSSH on the +mobile device and use "scp" or rsync for transfering files. +You can just copy your whole pypy-trunk directory over to your mobile +device - however, only these should be needed:: + pypy/lib + lib-python + pypy/translator/goal/pypy-c +It is neccessary that the ``pypy-c`` can find a "lib-python" and "pypy/lib" directory +if you want to successfully startup the interpreter on the device. -variant 2: using official maemo-installs ----------------------------------------------------------------- +Start ``pypy-c`` on the device and you should see something like:: -the following taken mostly from - - http://yankandpaste.blogspot.com/2008/08/maemo-diablo-sdk-install-on-ubuntu-804.html - -1. On ubuntu linux edit /etc/sysctl.conf to contain:: - - XXX [fijal] since it might freeze your machine, I suggest to add a - non-permanent way of doing it (echo 0 > /proc/sys/vm/vdso_enabled) - - XXX [fijal] on my machine vdso_enbled = 0 freezed machine and made in - unbootable without editing file first. It seems not to be needed - though. - - vm.vdso_enabled = 0 - vm.mmap_min_addr = 4096 - - and activate via "sysctl -p". (on some linuxes this might crash your computer) - This step is neccessary for getting a working scratchbox installation. - -2. Grab http://repository.maemo.org/stable/diablo/maemo-scratchbox-install_4.1.1.sh - and run it as root with "sh maemo-scratchbox-install_4.1.1.sh -u USERNAME" - so that you automatically get an account created within the virtual scratchbox - environment. After this step you should be able to perform ``/scratchbox/login`` - and get a funny prompt. - -3. Grab http://repository.maemo.org/stable/diablo/maemo-sdk-install_4.1.1.sh - and run it. For me only selecting "[x] runtime environment" worked whereas - installing the dev packages failed but that might have been a (reproducible - though) local download problem. After this step you should be able - to perform ``/scratchbox/login`` and land in a DIABLO_ARM target environment, - the code name for current Maemo. You should be able to execute "python2.5" - within the scratchbox environment. - -4. It might not be neccessary in your installation but in order to get - the scratchbox and python to work without strange warnings i found - a note that it helps to setup the newest qemu-arm compiler. - For this you need to svn-checkout - - http://qemu-arm-eabi.svn.sourceforge.net/svnroot/qemu-arm-eabi/trunk - - and follow the README. (a number of steps). - - -.. _`installation instructions`: http://www.scratchbox.org/documentation/user/scratchbox-1.0/html/installdoc.html -.. _`scratchbox`: http://scratchbox.org - - -Using a debian target (not recommended, does not work!) -+++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -in theory we don't need to install debian under scratchbox. in practice though, -if we want to run pypy-c with allworkingmodules we need to a way to install -correct libraries and include files. For example we should use etch and not -lenny, since libffi is in correct version there (4 vs 5). On the other -hand I had no luck installing python on etch.. - -To be able to run debian correctly you need to: - -1. Manually edit /scratchbox/devkits/debian-etch/etc/environment - to add ARCH=arm (instead of ARCH=...), - otherwise apt-get did not work. - -2. Go inside scratchbox and make /etc/apt/sources.list to contain: - deb ftp://ftp.fi.debian.org/debian/ lenny main contrib non-free - deb-src ftp://ftp.fi.debian.org/debian/ lenny main contrib non-free - -3. Run apt-get update && fakeroot apt-get install libc6 && fakeroot apt-get install python2.5-dev - -5. In order to have pypy-c with all working modules you also need following - packages: - - * libffi-dev - - * zlib1g-dev - * libbz2-dev From hpk at codespeak.net Thu Oct 30 06:12:28 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 30 Oct 2008 06:12:28 +0100 (CET) Subject: [pypy-svn] r59529 - pypy/trunk/pypy/doc Message-ID: <20081030051228.577D616A099@codespeak.net> Author: hpk Date: Thu Oct 30 06:12:27 2008 New Revision: 59529 Modified: pypy/trunk/pypy/doc/maemo.txt Log: fix ReST Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Thu Oct 30 06:12:27 2008 @@ -7,7 +7,7 @@ a usable Python Interpreter for Nokia's N810_ device. .. _N810: http://en.wikipedia.org/wiki/Nokia_N810 -.. _`Internet-Tabel-OS`: _http://en.wikipedia.org/wiki/Internet_Tablet_OS +.. _`Internet-Tablet-OS`: http://en.wikipedia.org/wiki/Internet_Tablet_OS .. _Maemo: http://www.maemo.org .. _Scratchbox: http://www.scratchbox.org .. _`INSTALL.txt`: http://tablets-dev.nokia.com/4.1/INSTALL.txt @@ -94,7 +94,7 @@ When being asked select the default "Runtime + Dev" packages. You do not need Closed source Nokia binaries for PyPy. This installation script will download "rootstraps" and create so called -"targets" and preselect the "DIABLO_ARMEL" target for ARM_ +"targets" and preselect the "DIABLO_ARMEL" target for ARM compilation. Within the targets a large number of packages will be pre-installed resulting in a base scratchbox environment that is usable for cross compilation of PyPy. @@ -162,7 +162,7 @@ It is neccessary that the ``pypy-c`` can find a "lib-python" and "pypy/lib" directory if you want to successfully startup the interpreter on the device. -Start ``pypy-c`` on the device and you should see something like:: +Start ``pypy-c`` on the device. From arigo at codespeak.net Thu Oct 30 10:54:47 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 10:54:47 +0100 (CET) Subject: [pypy-svn] r59530 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081030095447.DCDED169FB1@codespeak.net> Author: arigo Date: Thu Oct 30 10:54:46 2008 New Revision: 59530 Modified: pypy/trunk/pypy/objspace/std/test/test_typeobject.py pypy/trunk/pypy/objspace/std/typeobject.py Log: Minimal checking for the return value of a custom mro() method. Modified: pypy/trunk/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_typeobject.py Thu Oct 30 10:54:46 2008 @@ -901,3 +901,18 @@ raises(TypeError, setattr, list, 'foobar', 42) raises(TypeError, delattr, dict, 'keys') + def test_nontype_in_mro(self): + class OldStyle: + pass + class X(object): + pass + + class mymeta1(type): + def mro(self): + return [self, OldStyle, object] + mymeta1("Foo1", (object,), {}) # works + + class mymeta2(type): + def mro(self): + return [self, X(), object] + raises(TypeError, mymeta2, "Foo", (object,), {}) Modified: pypy/trunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/typeobject.py Thu Oct 30 10:54:46 2008 @@ -545,11 +545,21 @@ if not space.is_w(w_where, space.w_type): w_mro_meth = space.get(w_mro_func, w_self) w_mro = space.call_function(w_mro_meth) - w_self.mro_w = space.viewiterable(w_mro) - # do some checking here + mro_w = space.viewiterable(w_mro) + w_self.mro_w = validate_custom_mro(space, mro_w) return # done w_self.mro_w = w_self.compute_default_mro()[:] +def validate_custom_mro(space, mro_w): + # do some checking here. Note that unlike CPython, strange MROs + # cannot really segfault PyPy. At a minimum, we check that all + # the elements in the mro seem to be (old- or new-style) classes. + for w_class in mro_w: + if not space.abstract_isclass_w(w_class): + raise OperationError(space.w_TypeError, + space.wrap("mro() returned a non-class")) + return mro_w + # ____________________________________________________________ def call__Type(space, w_type, __args__): From arigo at codespeak.net Thu Oct 30 10:56:19 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 10:56:19 +0100 (CET) Subject: [pypy-svn] r59531 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030095619.D3106169FBD@codespeak.net> Author: arigo Date: Thu Oct 30 10:56:19 2008 New Revision: 59531 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Add a couple of TypeErrory lines in the test, and explain why. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 10:56:19 2008 @@ -1722,6 +1722,14 @@ class __metaclass__(type): def mro(self): return [self, dict, object] + # In CPython, the class creation above already raises + # TypeError, as a protection against the fact that + # instances of X would segfault it. In other PyPy + # implementations it would be ok to let the class X + # be created, but instead get a clean TypeError on the + # __setitem__ below. + x = object.__new__(X) + x[5] = 6 except TypeError: pass else: From arigo at codespeak.net Thu Oct 30 11:01:18 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 11:01:18 +0100 (CET) Subject: [pypy-svn] r59532 - in pypy/trunk/lib-python: . modified-2.5.2/test Message-ID: <20081030100118.0680116A007@codespeak.net> Author: arigo Date: Thu Oct 30 11:01:18 2008 New Revision: 59532 Added: pypy/trunk/lib-python/modified-2.5.2/test/test_coercion.py - copied, changed from r59521, pypy/trunk/lib-python/2.5.2/test/test_coercion.py Modified: pypy/trunk/lib-python/failure_list.txt Log: Marked this as implementation-specific, with justification. test_coercion now passes. Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Thu Oct 30 11:01:18 2008 @@ -14,9 +14,6 @@ test_codeccallbacks ! unknown test_codecs ! unknown test_coding ! hah. fix buildbot :-/ -test_coercion arigo look at test_prefix_binops, the other is probably too obscure - problem with prebuilt objects being equal in result list creation - test_commands ! unknown test_compile ! test_leading_newlines: impl detail; the rest: not good test_compiler ! unknown Copied: pypy/trunk/lib-python/modified-2.5.2/test/test_coercion.py (from r59521, pypy/trunk/lib-python/2.5.2/test/test_coercion.py) ============================================================================== --- pypy/trunk/lib-python/2.5.2/test/test_coercion.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_coercion.py Thu Oct 30 11:01:18 2008 @@ -2,7 +2,7 @@ import sys import warnings import unittest -from test.test_support import run_unittest, TestFailed +from test.test_support import run_unittest, TestFailed, check_impl_detail # Fake a number that implements numeric methods through __coerce__ class CoerceNumber: @@ -306,11 +306,17 @@ self.assertNotEquals(cmp(u'fish', evil_coercer), 0) self.assertNotEquals(cmp(slice(1), evil_coercer), 0) # ...but that this still works - class WackyComparer(object): - def __cmp__(slf, other): - self.assert_(other == 42, 'expected evil_coercer, got %r' % other) - return 0 - self.assertEquals(cmp(WackyComparer(), evil_coercer), 0) + if check_impl_detail: + # NB. I (arigo) would consider the following as implementation- + # specific. For example, in CPython, if we replace 42 with 42.0 + # both below and in CoerceTo() above, then the test fails. This + # hints that the behavior is really dependent on some obscure + # internal details. + class WackyComparer(object): + def __cmp__(slf, other): + self.assert_(other == 42, 'expected evil_coercer, got %r' % other) + return 0 + self.assertEquals(cmp(WackyComparer(), evil_coercer), 0) # ...and classic classes too, since that code path is a little different class ClassicWackyComparer: def __cmp__(slf, other): From arigo at codespeak.net Thu Oct 30 11:13:18 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 11:13:18 +0100 (CET) Subject: [pypy-svn] r59535 - pypy/trunk/pypy/module/_lsprof/test Message-ID: <20081030101318.E816416A000@codespeak.net> Author: arigo Date: Thu Oct 30 11:13:18 2008 New Revision: 59535 Modified: pypy/trunk/pypy/module/_lsprof/test/test_cprofile.py Log: Fix the test to expect built-in function calls, and to give a readable display of the differences in case of failure. Still skipped, but at least now we can start fixing :-) Modified: pypy/trunk/pypy/module/_lsprof/test/test_cprofile.py ============================================================================== --- pypy/trunk/pypy/module/_lsprof/test/test_cprofile.py (original) +++ pypy/trunk/pypy/module/_lsprof/test/test_cprofile.py Thu Oct 30 11:13:18 2008 @@ -113,22 +113,24 @@ res, prof = do_profiling(Profile) assert res[0] == 1000 - skip("when we reach this point, things seem to work; " - "but we need to review carefully what we expect as output") + skip("XXX FIX ME") for i, method in enumerate(methodnames): - if not res[i + 1] == self.expected_output[method]: - print method - print res[i + 1] - print self.expected_output[method] - one = res[i + 1].split("\n") - two = self.expected_output[method].split("\n") - for k in range(len(res[i + 1])): - if one[k] != two[k]: - print k - print one[k] - print two[k] - import pdb - pdb.set_trace() + got = res[i + 1] + expected = self.expected_output[method] + if got != expected: + print method, 'differs:' + print '---------- GOT: ----------' + print got + print '---------- EXPECTED: ----------' + print expected + print '----------' + for line1, line2 in zip(got.splitlines(), + expected.splitlines()): + if line1 != line2: + print 'Difference is here:' + print ' GOT:', line1.rstrip('\n') + print 'EXPECTED:', line2.rstrip('\n') + break assert 0 #assert res[i + 1] == self.expected_output[method] finally: @@ -136,79 +138,6 @@ expected_output = {} expected_output['print_stats'] = """\ - 98 function calls (78 primitive calls) in 1.000 CPU seconds - - Ordered by: standard name - - ncalls tottime percall cumtime percall filename:lineno(function) - 1 0.000 0.000 1.000 1.000 :0() - 1 0.000 0.000 0.000 0.000 ?:1() - 28 0.028 0.001 0.028 0.001 profilee.py:110(__getattr__) - 1 0.270 0.270 1.000 1.000 profilee.py:25(testfunc) - 23/3 0.150 0.007 0.170 0.057 profilee.py:35(factorial) - 20 0.020 0.001 0.020 0.001 profilee.py:48(mul) - 2 0.040 0.020 0.600 0.300 profilee.py:55(helper) - 4 0.116 0.029 0.120 0.030 profilee.py:73(helper1) - 2 0.000 0.000 0.140 0.070 profilee.py:84(helper2_indirect) - 8 0.312 0.039 0.400 0.050 profilee.py:88(helper2) - 8 0.064 0.008 0.080 0.010 profilee.py:98(subhelper) - - -""" -expected_output['print_callers'] = """\ - Ordered by: standard name - -Function was called by... - ncalls tottime cumtime -:0() <- -?:1() <- -profilee.py:110(__getattr__) <- 4 0.004 0.004 profilee.py:73(helper1) - 8 0.008 0.008 profilee.py:88(helper2) - 16 0.016 0.016 profilee.py:98(subhelper) -profilee.py:25(testfunc) <- 1 0.270 1.000 :0() -profilee.py:35(factorial) <- 1 0.014 0.130 profilee.py:25(testfunc) - 20/3 0.130 0.147 profilee.py:35(factorial) - 2 0.006 0.040 profilee.py:84(helper2_indirect) -profilee.py:48(mul) <- 20 0.020 0.020 profilee.py:35(factorial) -profilee.py:55(helper) <- 2 0.040 0.600 profilee.py:25(testfunc) -profilee.py:73(helper1) <- 4 0.116 0.120 profilee.py:55(helper) -profilee.py:84(helper2_indirect) <- 2 0.000 0.140 profilee.py:55(helper) -profilee.py:88(helper2) <- 6 0.234 0.300 profilee.py:55(helper) - 2 0.078 0.100 profilee.py:84(helper2_indirect) -profilee.py:98(subhelper) <- 8 0.064 0.080 profilee.py:88(helper2) - - -""" -expected_output['print_callees'] = """\ - Ordered by: standard name - -Function called... - ncalls tottime cumtime -:0() -> 1 0.270 1.000 profilee.py:25(testfunc) -?:1() -> -profilee.py:110(__getattr__) -> -profilee.py:25(testfunc) -> 1 0.014 0.130 profilee.py:35(factorial) - 2 0.040 0.600 profilee.py:55(helper) -profilee.py:35(factorial) -> 20/3 0.130 0.147 profilee.py:35(factorial) - 20 0.020 0.020 profilee.py:48(mul) -profilee.py:48(mul) -> -profilee.py:55(helper) -> 4 0.116 0.120 profilee.py:73(helper1) - 2 0.000 0.140 profilee.py:84(helper2_indirect) - 6 0.234 0.300 profilee.py:88(helper2) -profilee.py:73(helper1) -> 4 0.004 0.004 profilee.py:110(__getattr__) -profilee.py:84(helper2_indirect) -> 2 0.006 0.040 profilee.py:35(factorial) - 2 0.078 0.100 profilee.py:88(helper2) -profilee.py:88(helper2) -> 8 0.064 0.080 profilee.py:98(subhelper) - 8 0.008 0.008 profilee.py:110(__getattr__) -profilee.py:98(subhelper) -> 16 0.016 0.016 profilee.py:110(__getattr__) - - -""" - -# this is how stuff would look like if we trace built-in calls - -real_expected_output = {} -real_expected_output['print_stats'] = """\ 126 function calls (106 primitive calls) in 1.000 CPU seconds Ordered by: standard name @@ -232,7 +161,7 @@ """ -real_expected_output['print_callers'] = """\ +expected_output['print_callers'] = """\ Ordered by: standard name Function was called by... @@ -260,7 +189,7 @@ """ -real_expected_output['print_callees'] = """\ +expected_output['print_callees'] = """\ Ordered by: standard name Function called... From arigo at codespeak.net Thu Oct 30 12:09:26 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:09:26 +0100 (CET) Subject: [pypy-svn] r59538 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030110926.E3853169FBD@codespeak.net> Author: arigo Date: Thu Oct 30 12:09:26 2008 New Revision: 59538 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Typo (thanks jacob) Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:09:26 2008 @@ -1724,7 +1724,7 @@ return [self, dict, object] # In CPython, the class creation above already raises # TypeError, as a protection against the fact that - # instances of X would segfault it. In other PyPy + # instances of X would segfault it. In other Python # implementations it would be ok to let the class X # be created, but instead get a clean TypeError on the # __setitem__ below. From arigo at codespeak.net Thu Oct 30 12:19:18 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:19:18 +0100 (CET) Subject: [pypy-svn] r59539 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030111918.3EBF4169F86@codespeak.net> Author: arigo Date: Thu Oct 30 12:19:17 2008 New Revision: 59539 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Skip this (pretty much CPython internal) test if there is no __cmp__. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:19:17 2008 @@ -1967,6 +1967,9 @@ verify(10 not in p10) # Safety test for __cmp__ def unsafecmp(a, b): + if not hasattr(a, '__cmp__'): + return # some types don't have a __cmp__ any more in CPython, + # or never had e.g. in PyPy try: a.__class__.__cmp__(a, b) except TypeError: From arigo at codespeak.net Thu Oct 30 12:21:57 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:21:57 +0100 (CET) Subject: [pypy-svn] r59540 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030112157.F10E7169F86@codespeak.net> Author: arigo Date: Thu Oct 30 12:21:57 2008 New Revision: 59540 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Anything that showcases a crash caused by a print only if the print goes to a real file... only makes sense on CPython. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:21:57 2008 @@ -1984,28 +1984,29 @@ unsafecmp(1, 1L) unsafecmp(1L, 1) - class Letter(str): - def __new__(cls, letter): - if letter == 'EPS': - return str.__new__(cls) - return str.__new__(cls, letter) - def __str__(self): - if not self: - return 'EPS' - return self - - # sys.stdout needs to be the original to trigger the recursion bug - import sys - test_stdout = sys.stdout - sys.stdout = get_original_stdout() - try: - # nothing should actually be printed, this should raise an exception - print Letter('w') - except RuntimeError: - pass - else: - raise TestFailed, "expected a RuntimeError for print recursion" - sys.stdout = test_stdout + if check_impl_detail: + class Letter(str): + def __new__(cls, letter): + if letter == 'EPS': + return str.__new__(cls) + return str.__new__(cls, letter) + def __str__(self): + if not self: + return 'EPS' + return self + + # sys.stdout needs to be the original to trigger the recursion bug + import sys + test_stdout = sys.stdout + sys.stdout = get_original_stdout() + try: + # nothing should actually be printed, this should raise an exception + print Letter('w') + except RuntimeError: + pass + else: + raise TestFailed, "expected a RuntimeError for print recursion" + sys.stdout = test_stdout def weakrefs(): if verbose: print "Testing weak references..." From arigo at codespeak.net Thu Oct 30 12:23:23 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:23:23 +0100 (CET) Subject: [pypy-svn] r59541 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030112323.B1AF6169FA2@codespeak.net> Author: arigo Date: Thu Oct 30 12:23:23 2008 New Revision: 59541 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: More gc_collect()s. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:23:23 2008 @@ -2017,6 +2017,7 @@ r = weakref.ref(c) verify(r() is c) del c + gc_collect() verify(r() is None) del r class NoWeak(object): @@ -2034,6 +2035,7 @@ r = weakref.ref(yes) verify(r() is yes) del yes + gc_collect() verify(r() is None) del r From arigo at codespeak.net Thu Oct 30 12:38:02 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:38:02 +0100 (CET) Subject: [pypy-svn] r59543 - in pypy/trunk/pypy/module/__builtin__: . test Message-ID: <20081030113802.F08F7169F86@codespeak.net> Author: arigo Date: Thu Oct 30 12:38:00 2008 New Revision: 59543 Modified: pypy/trunk/pypy/module/__builtin__/descriptor.py pypy/trunk/pypy/module/__builtin__/test/test_descriptor.py Log: Test and fix for a new 2.5 feature. Modified: pypy/trunk/pypy/module/__builtin__/descriptor.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/descriptor.py (original) +++ pypy/trunk/pypy/module/__builtin__/descriptor.py Thu Oct 30 12:38:00 2008 @@ -101,6 +101,11 @@ self.w_fset = w_fset self.w_fdel = w_fdel self.w_doc = w_doc + # our __doc__ comes from the getter if we don't have an explicit one + if space.is_w(self.w_doc, space.w_None): + w_getter_doc = space.findattr(self.w_fget, space.wrap("__doc__")) + if w_getter_doc is not None: + self.w_doc = w_getter_doc def new(space, w_subtype, w_fget=None, w_fset=None, w_fdel=None, w_doc=None): w_result = space.allocate_instance(W_Property, w_subtype) Modified: pypy/trunk/pypy/module/__builtin__/test/test_descriptor.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/test/test_descriptor.py (original) +++ pypy/trunk/pypy/module/__builtin__/test/test_descriptor.py Thu Oct 30 12:38:00 2008 @@ -237,6 +237,11 @@ A.x = property(lambda x: x, lambda x, y: x, lambda x:x, 'xxx') assert A.x.__doc__ == 'xxx' + # new in 2.5: + def foo(x): + "my docstring" + assert property(foo).__doc__ == "my docstring" + def test_property(self): class C(object): def getx(self): From arigo at codespeak.net Thu Oct 30 12:39:53 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:39:53 +0100 (CET) Subject: [pypy-svn] r59544 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030113953.03C0E169F86@codespeak.net> Author: arigo Date: Thu Oct 30 12:39:53 2008 New Revision: 59544 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: This is clearly a bug in the test. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:39:53 2008 @@ -2314,7 +2314,7 @@ __slots__ = ['prec'] def __init__(self, value=0.0, prec=12): self.prec = int(prec) - float.__init__(value) + float.__init__(self, value) def __repr__(self): return "%.*g" % (self.prec, self) vereq(repr(precfloat(1.1)), "1.1") From arigo at codespeak.net Thu Oct 30 12:41:49 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:41:49 +0100 (CET) Subject: [pypy-svn] r59545 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030114149.03200169F5F@codespeak.net> Author: arigo Date: Thu Oct 30 12:41:49 2008 New Revision: 59545 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Generalize the catch. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:41:49 2008 @@ -2843,7 +2843,7 @@ raise TestFailed, "shouldn't allow %r.__class__ = %r" % (x, C) try: delattr(x, "__class__") - except TypeError: + except (TypeError, AttributeError): pass else: raise TestFailed, "shouldn't allow del %r.__class__" % x From fijal at codespeak.net Thu Oct 30 12:42:42 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 12:42:42 +0100 (CET) Subject: [pypy-svn] r59546 - pypy/trunk/pypy/module/zipimport/test Message-ID: <20081030114242.DF5A8169F5F@codespeak.net> Author: fijal Date: Thu Oct 30 12:42:42 2008 New Revision: 59546 Modified: pypy/trunk/pypy/module/zipimport/test/test_zipimport.py Log: Hack a bit differently. I'm completely lost :-( Modified: pypy/trunk/pypy/module/zipimport/test/test_zipimport.py ============================================================================== --- pypy/trunk/pypy/module/zipimport/test/test_zipimport.py (original) +++ pypy/trunk/pypy/module/zipimport/test/test_zipimport.py Thu Oct 30 12:42:42 2008 @@ -94,8 +94,13 @@ while sys.path[0].endswith('.zip'): sys.path.pop(0) """) - space.setattr(space.getbuiltinmodule('sys'), - space.wrap('modules'), self.w_modules) + space.appexec([self.w_modules], """(modules): + import sys + for module in sys.modules: + if module not in modules: + del sys.modules[module] + """) + self.w_modules = [] def test_cache(self): self.writefile(self, 'x.py', 'y') @@ -134,6 +139,7 @@ for key, val in expected.items(): assert mod.__dict__[key] == val assert mod.__file__.endswith('.zip'+os.sep+'uuu.py') + del sys.modules['uuu'] def test_pyc(self): import sys, os From arigo at codespeak.net Thu Oct 30 12:44:18 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:44:18 +0100 (CET) Subject: [pypy-svn] r59547 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030114418.3A83F169F5F@codespeak.net> Author: arigo Date: Thu Oct 30 12:44:17 2008 New Revision: 59547 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Typo in the original test's failure path. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:44:17 2008 @@ -2945,7 +2945,8 @@ except (TypeError, AttributeError): pass else: - raise TestFaied, "%r's __dict__ can be deleted" % e + raise TestFailed, "%s instance __dict__ can be deleted" % ( + ExceptionType,) def pickles(): From arigo at codespeak.net Thu Oct 30 12:51:12 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:51:12 +0100 (CET) Subject: [pypy-svn] r59548 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030115112.47D2F169F91@codespeak.net> Author: arigo Date: Thu Oct 30 12:51:11 2008 New Revision: 59548 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Fix a test to not rely on whether 'del ValueError().__dict__' is allowed or not. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:51:11 2008 @@ -2932,6 +2932,16 @@ mod.__dict__["spam"] = "eggs" # Exception's __dict__ can be replaced, but not deleted + # (at least not any more than regular exception's __dict__ can + # be deleted; on CPython it is not the case, whereas on PyPy they + # can, just like any other new-style instance's __dict__.) + def can_delete_dict(e): + try: + del e.__dict__ + except (TypeError, AttributeError): + return False + else: + return True class Exception1(Exception, Base): pass class Exception2(Base, Exception): @@ -2940,13 +2950,7 @@ e = ExceptionType() e.__dict__ = {"a": 1} vereq(e.a, 1) - try: - del e.__dict__ - except (TypeError, AttributeError): - pass - else: - raise TestFailed, "%s instance __dict__ can be deleted" % ( - ExceptionType,) + assert can_delete_dict(e) == can_delete_dict(ValueError()) def pickles(): From arigo at codespeak.net Thu Oct 30 12:52:01 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:52:01 +0100 (CET) Subject: [pypy-svn] r59549 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030115201.4C203169F91@codespeak.net> Author: arigo Date: Thu Oct 30 12:52:00 2008 New Revision: 59549 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Another of these. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:52:00 2008 @@ -3370,6 +3370,7 @@ c = C() vereq(log, []) del c + gc_collect() vereq(log, [1]) class D(object): pass From fijal at codespeak.net Thu Oct 30 12:52:27 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 12:52:27 +0100 (CET) Subject: [pypy-svn] r59550 - pypy/trunk/pypy/module/zipimport/test Message-ID: <20081030115227.9221A169FA2@codespeak.net> Author: fijal Date: Thu Oct 30 12:52:26 2008 New Revision: 59550 Modified: pypy/trunk/pypy/module/zipimport/test/test_zipimport.py Log: I *think* I finally got the idea Modified: pypy/trunk/pypy/module/zipimport/test/test_zipimport.py ============================================================================== --- pypy/trunk/pypy/module/zipimport/test/test_zipimport.py (original) +++ pypy/trunk/pypy/module/zipimport/test/test_zipimport.py Thu Oct 30 12:52:26 2008 @@ -84,8 +84,9 @@ w_cache = space.getattr(space.getbuiltinmodule('zipimport'), space.wrap('_zip_directory_cache')) space.call_function(space.getattr(w_cache, space.wrap('clear'))) - self.w_modules = space.getattr(space.getbuiltinmodule('sys'), - space.wrap('modules')) + self.w_modules = space.call_method( + space.getattr(space.getbuiltinmodule('sys'), + space.wrap('modules')), 'copy') def teardown_method(self, meth): space = self.space @@ -96,7 +97,7 @@ """) space.appexec([self.w_modules], """(modules): import sys - for module in sys.modules: + for module in sys.modules.copy(): if module not in modules: del sys.modules[module] """) @@ -139,7 +140,6 @@ for key, val in expected.items(): assert mod.__dict__[key] == val assert mod.__file__.endswith('.zip'+os.sep+'uuu.py') - del sys.modules['uuu'] def test_pyc(self): import sys, os From arigo at codespeak.net Thu Oct 30 12:53:21 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:53:21 +0100 (CET) Subject: [pypy-svn] r59551 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030115321.172B4169FA2@codespeak.net> Author: arigo Date: Thu Oct 30 12:53:20 2008 New Revision: 59551 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Generalize this check. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:53:20 2008 @@ -3466,7 +3466,7 @@ vereq(hasattr(m, "__name__"), 0) vereq(hasattr(m, "__file__"), 0) vereq(hasattr(m, "foo"), 0) - vereq(m.__dict__, None) + assert not m.__dict__ # None or {} are both reasonable answers m.foo = 1 vereq(m.__dict__, {"foo": 1}) From arigo at codespeak.net Thu Oct 30 12:59:34 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 12:59:34 +0100 (CET) Subject: [pypy-svn] r59552 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030115934.D2BD9169FD0@codespeak.net> Author: arigo Date: Thu Oct 30 12:59:34 2008 New Revision: 59552 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Mark as "detail" a test that relies on the fact that __del__ is called again on the same instance, after resurrection. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 12:59:34 2008 @@ -3654,10 +3654,14 @@ # If that didn't blow up, it's also interesting to see whether clearing # the last container slot works: that will attempt to delete c again, # which will cause c to get appended back to the container again "during" - # the del. - del C.container[-1] + # the del. On non-CPython implementations, however, __del__ is not + # called again. + gc_collect() vereq(len(C.container), 1) - vereq(C.container[-1].attr, 42) + del C.container[-1] + if check_impl_detail: + vereq(len(C.container), 1) + vereq(C.container[-1].attr, 42) # Make c mortal again, so that the test framework with -l doesn't report # it as a leak. From arigo at codespeak.net Thu Oct 30 13:03:44 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 13:03:44 +0100 (CET) Subject: [pypy-svn] r59553 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030120344.BFCE1169FD0@codespeak.net> Author: arigo Date: Thu Oct 30 13:03:44 2008 New Revision: 59553 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Ah ah ah. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 13:03:44 2008 @@ -3688,7 +3688,8 @@ pass class C(A,B) : __slots__=() - vereq(C.__basicsize__, B.__basicsize__) + if check_impl_detail: + vereq(C.__basicsize__, B.__basicsize__) verify(hasattr(C, '__dict__')) verify(hasattr(C, '__weakref__')) C().x = 2 From arigo at codespeak.net Thu Oct 30 13:04:53 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 13:04:53 +0100 (CET) Subject: [pypy-svn] r59554 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030120453.B5CDC169F00@codespeak.net> Author: arigo Date: Thu Oct 30 13:04:53 2008 New Revision: 59554 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Generalize the catch. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 13:04:53 2008 @@ -3788,7 +3788,7 @@ try: del D.__bases__ - except TypeError: + except (TypeError, AttributeError): pass else: raise TestFailed, "shouldn't be able to delete .__bases__" From arigo at codespeak.net Thu Oct 30 13:15:36 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 13:15:36 +0100 (CET) Subject: [pypy-svn] r59555 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030121536.83B7C169FD4@codespeak.net> Author: arigo Date: Thu Oct 30 13:15:36 2008 New Revision: 59555 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: The whole test is an implementation detail, really, with such a print at the beginning. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 13:15:36 2008 @@ -1,7 +1,7 @@ # Test enhancements related to descriptors and new-style classes from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout -from test.test_support import check_impl_detail, gc_collect +from test.test_support import check_impl_detail, impl_detail, gc_collect from copy import deepcopy import warnings import types @@ -4006,6 +4006,7 @@ __metaclass__ = M veris(type(C.__dict__), type(B.__dict__)) + at impl_detail def meth_class_get(): # Full coverage of descrobject.c::classmethod_get() if verbose: From fijal at codespeak.net Thu Oct 30 13:34:45 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 13:34:45 +0100 (CET) Subject: [pypy-svn] r59556 - pypy/trunk/pypy/module/zipimport/test Message-ID: <20081030123445.7DFAC16A00F@codespeak.net> Author: fijal Date: Thu Oct 30 13:34:43 2008 New Revision: 59556 Modified: pypy/trunk/pypy/module/zipimport/test/test_zipimport.py Log: I hope this is final checkin here for today :] Modified: pypy/trunk/pypy/module/zipimport/test/test_zipimport.py ============================================================================== --- pypy/trunk/pypy/module/zipimport/test/test_zipimport.py (original) +++ pypy/trunk/pypy/module/zipimport/test/test_zipimport.py Thu Oct 30 13:34:43 2008 @@ -59,7 +59,7 @@ import time from zipfile import ZipFile, ZipInfo z = ZipFile(self.zipfile, 'w') - write_files = getattr(self, 'write_files', []) + write_files = self.write_files write_files.append((filename, data)) for filename, data in write_files: zinfo = ZipInfo(filename, time.localtime(self.now)) @@ -78,9 +78,7 @@ space = self.space name = "test_%s_%s.zip" % (self.__class__.__name__, meth.__name__) self.w_zipfile = space.wrap(str(self.tmpdir.join(name))) - space.appexec([space.wrap(self)], """(self): - self.write_files = [] - """) + self.w_write_files = space.newlist([]) w_cache = space.getattr(space.getbuiltinmodule('zipimport'), space.wrap('_zip_directory_cache')) space.call_function(space.getattr(w_cache, space.wrap('clear'))) @@ -243,8 +241,8 @@ """ import os import zipimport - self.writefile( - self, os.sep.join(("directory", "package", "__init__.py")), "") + self.writefile(self, + os.sep.join(("directory", "package", "__init__.py")), "") importer = zipimport.zipimporter(self.zipfile + "/directory") l = [i for i in zipimport._zip_directory_cache] assert len(l) From arigo at codespeak.net Thu Oct 30 14:26:26 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 14:26:26 +0100 (CET) Subject: [pypy-svn] r59557 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081030132626.A4FD8169FD6@codespeak.net> Author: arigo Date: Thu Oct 30 14:26:24 2008 New Revision: 59557 Modified: pypy/trunk/pypy/objspace/std/test/test_typeobject.py pypy/trunk/pypy/objspace/std/typeobject.py Log: Easiest fix today: just re-comment the commented-out code :-) Modified: pypy/trunk/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_typeobject.py Thu Oct 30 14:26:24 2008 @@ -916,3 +916,10 @@ def mro(self): return [self, X(), object] raises(TypeError, mymeta2, "Foo", (object,), {}) + + def test_init_must_return_none(self): + class X(object): + def __init__(self): + return 0 + raises(TypeError, X) + Modified: pypy/trunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/typeobject.py Thu Oct 30 14:26:24 2008 @@ -578,9 +578,9 @@ if space.is_true(space.isinstance(w_newobject, w_type)): w_descr = space.lookup(w_newobject, '__init__') w_result = space.get_and_call_args(w_descr, w_newobject, __args__) -## if not space.is_w(w_result, space.w_None): -## raise OperationError(space.w_TypeError, -## space.wrap("__init__() should return None")) + if not space.is_w(w_result, space.w_None): + raise OperationError(space.w_TypeError, + space.wrap("__init__() should return None")) return w_newobject def issubtype__Type_Type(space, w_type1, w_type2): From arigo at codespeak.net Thu Oct 30 14:31:14 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 14:31:14 +0100 (CET) Subject: [pypy-svn] r59558 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030133114.3B5EC169F05@codespeak.net> Author: arigo Date: Thu Oct 30 14:31:12 2008 New Revision: 59558 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Make the test for flexible. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 14:31:12 2008 @@ -4222,8 +4222,14 @@ verify(l.__add__ != [5].__add__) verify(l.__add__ != l.__mul__) verify(l.__add__.__name__ == '__add__') - verify(l.__add__.__self__ is l) - verify(l.__add__.__objclass__ is list) + if hasattr(l.__add__, '__self__'): + # CPython + verify(l.__add__.__self__ is l) + verify(l.__add__.__objclass__ is list) + else: + # Python implementations where [].__add__ is a normal bound method + verify(l.__add__.im_self is l) + verify(l.__add__.im_class is list) vereq(l.__add__.__doc__, list.__add__.__doc__) try: hash(l.__add__) From arigo at codespeak.net Thu Oct 30 14:44:05 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 14:44:05 +0100 (CET) Subject: [pypy-svn] r59559 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030134405.AE863168452@codespeak.net> Author: arigo Date: Thu Oct 30 14:44:03 2008 New Revision: 59559 Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Log: Make this test closer than the original. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 14:44:03 2008 @@ -169,10 +169,10 @@ def dicts(): if verbose: print "Testing dict operations..." - testbinop({1:2}, {2:1}, False, "a == b", "__eq__") - testbinop({1:2}, {2:1}, True, "a != b", "__ne__") if hasattr(dict, '__cmp__'): # PyPy has only rich comparison on dicts testbinop({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__") + else: + testbinop({1:2}, {2:1}, True, "a < b", "__lt__") testbinop({1:2,3:4}, 1, 1, "b in a", "__contains__") testbinop({1:2,3:4}, 2, 0, "b in a", "__contains__") testbinop({1:2,3:4}, 1, 2, "a[b]", "__getitem__") From antocuni at codespeak.net Thu Oct 30 14:50:32 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 30 Oct 2008 14:50:32 +0100 (CET) Subject: [pypy-svn] r59560 - in pypy/branch/oo-jit/pypy/jit/codegen: . cli cli/test Message-ID: <20081030135032.ED3D5169F33@codespeak.net> Author: antocuni Date: Thu Oct 30 14:50:32 2008 New Revision: 59560 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py pypy/branch/oo-jit/pypy/jit/codegen/model.py Log: add some missing operations to ReplayBuilder, and add support for all possible types in ArgsManager. More tests pass :-) Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/args_manager.py Thu Oct 30 14:50:32 2008 @@ -12,7 +12,7 @@ def _group_args_by_type(self, args_gv): clitype2gv = {} for gv_arg in args_gv: - clitype = self._normalize_type(gv_arg.getCliType()) + clitype, _ = self._normalize_type(gv_arg.getCliType()) clitype2gv.setdefault(clitype, []).append(gv_arg) return clitype2gv @@ -33,6 +33,9 @@ i = 0 for gv_arg in args_gv: self.ldelem(meth, i, field, elemtype) + # perform the cast if needed + if elemtype == typeof(System.Object): + meth.il.Emit(OpCodes.Castclass, gv_arg.getCliType()) gv_arg.store(meth) i+=1 @@ -53,15 +56,23 @@ meth.il.Emit(OpCodes.Ldelem, elemtype) def _normalize_type(self, clitype): - # XXX: generalize! - if clitype == typeof(System.UInt32): - return typeof(System.Int32) - return clitype + # we have four kind of types: + # - integer types up to 32 bit + # - 64 bit integers + # - 64 bit floats + # - reference types (objects) + if clitype == typeof(System.Double): + return clitype, 'floats' + elif clitype == typeof(System.Int64): + return clitype, 'longs' # XXX: implement it in pypylib + elif clitype.get_IsPrimitive(): + return typeof(System.Int32), 'ints' + else: + # assume it's a reference type + return typeof(System.Object), 'objs' def _get_array(self, clitype): - if clitype == typeof(System.Int32): - field = typeof(InputArgs).GetField('ints') - else: - assert False + clitype, name = self._normalize_type(clitype) + field = typeof(InputArgs).GetField(name) ftype = field.get_FieldType() return field, ftype.GetElementType() Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_interpreter.py Thu Oct 30 14:50:32 2008 @@ -42,10 +42,12 @@ func = compile_graph(graph, translator, nowrap=True) return func(*values) - def check_insns(self, expected=None, **counts): "Cannot check instructions in the generated assembler." + def check_flexswitches(self, expected_count): + "Cannot check instructions in the generated assembler." + class TestRainbowCli(CompiledCliMixin, RainbowTest): # for the individual tests see Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py Thu Oct 30 14:50:32 2008 @@ -10,9 +10,6 @@ def skip(self): py.test.skip('in progress') - remembers_across_mp = skip - test_virtual_list_copy = skip - test_raise_result_mixup = skip test_promote_class = skip test_promote_class_vstruct = skip test_read___class___after_promotion = skip Modified: pypy/branch/oo-jit/pypy/jit/codegen/model.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/model.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/model.py Thu Oct 30 14:50:32 2008 @@ -529,3 +529,27 @@ def genop_absorb_place(self, place): return dummy_var + + def genop_cast_int_to_ptr(self, kind, gv_int): + return dummy_var + + def genop_instanceof(self, gv_obj, alloctoken): + return dummy_var + + def genop_new(self, alloctoken): + return dummy_var + + def genop_oogetfield(self, fieldtoken, gv_obj): + return dummy_var + + def genop_ooisnull(self, gv_obj): + return dummy_var + + def genop_oonewarray(self, alloctoken, gv_length): + return dummy_var + + def genop_oononnull(self, gv_obj): + return dummy_var + + def genop_oosetfield(self, fieldtoken, gv_obj, gv_value): + return None From arigo at codespeak.net Thu Oct 30 15:00:52 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 15:00:52 +0100 (CET) Subject: [pypy-svn] r59561 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030140052.E5F8416853B@codespeak.net> Author: arigo Date: Thu Oct 30 15:00:51 2008 New Revision: 59561 Modified: pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py pypy/trunk/lib-python/modified-2.5.2/test/test_file.py pypy/trunk/lib-python/modified-2.5.2/test/test_set.py pypy/trunk/lib-python/modified-2.5.2/test/test_support.py pypy/trunk/lib-python/modified-2.5.2/test/test_weakref.py Log: Add an argument to the test_support.impl_detail decorator to specify the reason for which we consider it an implementation detail. Modified: pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/list_tests.py Thu Oct 30 15:00:51 2008 @@ -513,7 +513,7 @@ a[::2] = tuple(range(5)) self.assertEqual(a, self.type2test([0, 1, 1, 3, 2, 5, 3, 7, 4, 9])) - @test_support.impl_detail + @test_support.impl_detail("list() might call __len__() or not") def test_constructor_exception_handling(self): # Bug #1242657 class F(object): Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_descr.py Thu Oct 30 15:00:51 2008 @@ -4006,7 +4006,7 @@ __metaclass__ = M veris(type(C.__dict__), type(B.__dict__)) - at impl_detail + at impl_detail("testing an internal kind of method object") def meth_class_get(): # Full coverage of descrobject.c::classmethod_get() if verbose: Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_file.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_file.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_file.py Thu Oct 30 15:00:51 2008 @@ -220,7 +220,7 @@ finally: os.unlink(TESTFN) - @impl_detail + @impl_detail() def testIteration(self): # Test the complex interaction when mixing file-iteration and the # various read* methods. Ostensibly, the mixture could just be tested Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_set.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_set.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_set.py Thu Oct 30 15:00:51 2008 @@ -278,7 +278,7 @@ fo.close() os.remove(test_support.TESTFN) - @test_support.impl_detail + @test_support.impl_detail("depends on how many times __hash__ is called") def test_do_not_rehash_dict_keys(self): n = 10 d = dict.fromkeys(map(HashCountingInt, xrange(n))) @@ -515,7 +515,7 @@ s.__init__(self.otherword) self.assertEqual(s, set(self.word)) - @test_support.impl_detail + @test_support.impl_detail("checks an internal optimization") def test_singleton_empty_frozenset(self): f = frozenset() efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''), @@ -686,7 +686,7 @@ self.assert_(v in self.values) setiter = iter(self.set) - @test_support.impl_detail + @test_support.impl_detail("__length_hint__ is internal and undocumented") def test__length_hint(self): # note: __length_hint__ is an internal undocumented API, # don't rely on it in your own programs Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_support.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_support.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_support.py Thu Oct 30 15:00:51 2008 @@ -536,18 +536,21 @@ check_impl_detail = (hasattr(sys, 'subversion') and sys.subversion[0] == 'CPython') -def impl_detail(f): +def impl_detail(reason="CPython-specific implementation detail"): """A decorator to skip a whole function if not running on top of CPython. """ - if check_impl_detail: - return f - else: - def _skip_check_impl_detail(*args, **kwds): - if verbose: - sys.stderr.write("Skipping %s checking CPython-specific " - "implementation details\n" % (f.__name__,)) - return - return _skip_check_impl_detail + assert isinstance(reason, basestring) + def decorator(f): + if check_impl_detail: + return f + else: + def _skip_check_impl_detail(*args, **kwds): + if verbose: + sys.stderr.write("Skipping %s: %s\n" % (f.__name__, + reason)) + return + return _skip_check_impl_detail + return decorator def gc_collect(): """Force as many objects as possible to be collected. Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_weakref.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_weakref.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_weakref.py Thu Oct 30 15:00:51 2008 @@ -528,7 +528,7 @@ del c1, c2, C, D gc.collect() - @test_support.impl_detail + @test_support.impl_detail("details of weakref behavior") def test_callback_in_cycle_resurrection(self): # We can't guarrantee the behaviour tested with our # current weakref implementations. @@ -579,7 +579,7 @@ gc.collect() self.assertEqual(alist, []) - @test_support.impl_detail + @test_support.impl_detail("details of weakref behavior") def test_callbacks_on_callback(self): # See test_callback_in_cycle_resurrection above import gc From arigo at codespeak.net Thu Oct 30 15:25:59 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 15:25:59 +0100 (CET) Subject: [pypy-svn] r59564 - pypy/trunk/lib-python/modified-2.5.2/test Message-ID: <20081030142559.08C76169F0B@codespeak.net> Author: arigo Date: Thu Oct 30 15:25:58 2008 New Revision: 59564 Modified: pypy/trunk/lib-python/modified-2.5.2/test/string_tests.py Log: Definitely an impl detail. Modified: pypy/trunk/lib-python/modified-2.5.2/test/string_tests.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/string_tests.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/string_tests.py Thu Oct 30 15:25:58 2008 @@ -1149,9 +1149,10 @@ self.assert_(s1 is not s2) self.assert_(type(s2) is t) - s1 = t("abcd") - s2 = t().join([s1]) - self.assert_(s1 is s2) + if test_support.check_impl_detail: + s1 = t("abcd") + s2 = t().join([s1]) + self.assert_(s1 is s2) # Should also test mixed-type join. if t is unicode: From arigo at codespeak.net Thu Oct 30 15:39:08 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 15:39:08 +0100 (CET) Subject: [pypy-svn] r59565 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20081030143908.161B1169F87@codespeak.net> Author: arigo Date: Thu Oct 30 15:39:06 2008 New Revision: 59565 Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py pypy/trunk/pypy/objspace/std/unicodetype.py Log: Test and fix. The test comes from CPython. Modified: pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_unicodeobject.py Thu Oct 30 15:39:06 2008 @@ -702,3 +702,9 @@ b = B() s = '%s %s' % (b, a) assert s == u'foo baz' + + def test_str_subclass(self): + class Foo9(str): + def __unicode__(self): + return u"world" + assert unicode(Foo9("hello")) == u"world" Modified: pypy/trunk/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodetype.py (original) +++ pypy/trunk/pypy/objspace/std/unicodetype.py Thu Oct 30 15:39:06 2008 @@ -212,22 +212,16 @@ return w_retval def unicode_from_object(space, w_obj): - if space.is_true(space.isinstance(w_obj, space.w_str)): + if space.is_w(space.type(w_obj), space.w_str): w_res = w_obj else: - try: - # XXX should we have a space.unicode so we can go through - # descroperation? - w_unicode_method = space.getattr(w_obj, space.wrap("__unicode__")) - except OperationError, e: - if e.match(space, space.w_AttributeError): - w_res = space.str(w_obj) - else: - raise + w_unicode_method = space.lookup(w_obj, "__unicode__") + if w_unicode_method is not None: + w_res = space.get_and_call_function(w_unicode_method, w_obj) else: - w_res = space.call_function(w_unicode_method) - if space.is_true(space.isinstance(w_res, space.w_unicode)): - return w_res + w_res = space.str(w_obj) + if space.is_true(space.isinstance(w_res, space.w_unicode)): + return w_res return unicode_from_encoded_object(space, w_res, None, "strict") def unicode_from_string(space, w_str): @@ -267,10 +261,7 @@ w_value = w_obj else: if encoding is None and errors is None: - if space.is_true(space.isinstance(w_obj, space.w_str)): - w_value = unicode_from_string(space, w_obj) - else: - w_value = unicode_from_object(space, w_obj) + w_value = unicode_from_object(space, w_obj) else: w_value = unicode_from_encoded_object(space, w_obj, encoding, errors) From arigo at codespeak.net Thu Oct 30 16:22:01 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 16:22:01 +0100 (CET) Subject: [pypy-svn] r59568 - pypy/trunk/pypy/translator/goal Message-ID: <20081030152201.663C5169FC5@codespeak.net> Author: arigo Date: Thu Oct 30 16:22:00 2008 New Revision: 59568 Modified: pypy/trunk/pypy/translator/goal/app_main.py Log: Hack hack. Modified: pypy/trunk/pypy/translator/goal/app_main.py ============================================================================== --- pypy/trunk/pypy/translator/goal/app_main.py (original) +++ pypy/trunk/pypy/translator/goal/app_main.py Thu Oct 30 16:22:00 2008 @@ -426,6 +426,11 @@ except OSError: return None + # stick the current sys.path into $PYTHONPATH, so that CPython still + # finds its own extension modules :-/ + import os + os.environ['PYTHONPATH'] = ':'.join(sys.path) + from pypy.module.sys.version import PYPY_VERSION sys.pypy_version_info = PYPY_VERSION sys.pypy_initial_path = pypy_initial_path From fijal at codespeak.net Thu Oct 30 16:23:28 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 16:23:28 +0100 (CET) Subject: [pypy-svn] r59569 - pypy/trunk/pypy/module/__builtin__/test Message-ID: <20081030152328.B30BC169FE5@codespeak.net> Author: fijal Date: Thu Oct 30 16:23:28 2008 New Revision: 59569 Modified: pypy/trunk/pypy/module/__builtin__/test/test_import.py Log: Fix import Modified: pypy/trunk/pypy/module/__builtin__/test/test_import.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/test/test_import.py (original) +++ pypy/trunk/pypy/module/__builtin__/test/test_import.py Thu Oct 30 16:23:28 2008 @@ -627,7 +627,7 @@ def test_PYTHONPATH_takes_precedence(space): if sys.platform == "win32": py.test.skip("unresolved issues with win32 shell quoting rules") - from pypy.interpreter.test.test_py import pypypath + from pypy.interpreter.test.test_zpy import pypypath extrapath = udir.ensure("pythonpath", dir=1) extrapath.join("urllib.py").write("print 42\n") old = os.environ.get('PYTHONPATH', None) From fijal at codespeak.net Thu Oct 30 16:29:03 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 16:29:03 +0100 (CET) Subject: [pypy-svn] r59570 - pypy/build/bot2/pypybuildbot Message-ID: <20081030152903.55D55169FC0@codespeak.net> Author: fijal Date: Thu Oct 30 16:29:02 2008 New Revision: 59570 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: bump timeout (a bit arbitrarily though) Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Thu Oct 30 16:29:02 2008 @@ -100,7 +100,7 @@ "--config=~/machine_cfg.py", "--root=pypy"], logfiles={'pytestLog': 'testrun.log'}, - timeout = 2400, + timeout = 8000, env={"PYTHONPATH": ['.']})) class PyPyTranslatedLibPythonTestFactory(factory.BuildFactory): From fijal at codespeak.net Thu Oct 30 16:33:31 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 16:33:31 +0100 (CET) Subject: [pypy-svn] r59571 - pypy/trunk/pypy/lib/app_test Message-ID: <20081030153331.08FBD169FD0@codespeak.net> Author: fijal Date: Thu Oct 30 16:33:29 2008 New Revision: 59571 Modified: pypy/trunk/pypy/lib/app_test/test_binascii.py Log: This is exact test from CPython's test suite Modified: pypy/trunk/pypy/lib/app_test/test_binascii.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/test_binascii.py (original) +++ pypy/trunk/pypy/lib/app_test/test_binascii.py Thu Oct 30 16:33:29 2008 @@ -128,7 +128,7 @@ pass else: fail("binascii.a2b_qp(**{1:1}) didn't raise TypeError") - assert binascii.a2b_qp("= ") == "" + assert binascii.a2b_qp("= ") == "= " assert binascii.a2b_qp("==") == "=" assert binascii.a2b_qp("=AX") == "=AX" raises(TypeError, binascii.b2a_qp, foo="bar") From arigo at codespeak.net Thu Oct 30 16:33:38 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 16:33:38 +0100 (CET) Subject: [pypy-svn] r59572 - in pypy/trunk/pypy: . module/struct/test Message-ID: <20081030153338.C7E7A169FF1@codespeak.net> Author: arigo Date: Thu Oct 30 16:33:38 2008 New Revision: 59572 Modified: pypy/trunk/pypy/conftest.py pypy/trunk/pypy/module/struct/test/test_struct.py Log: Tweak this test, and the conftest, to pass a bit more tests when run with -A. Modified: pypy/trunk/pypy/conftest.py ============================================================================== --- pypy/trunk/pypy/conftest.py (original) +++ pypy/trunk/pypy/conftest.py Thu Oct 30 16:33:38 2008 @@ -99,6 +99,9 @@ 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") @@ -369,7 +372,7 @@ # if the value is a function living on the class, # don't turn it into a bound method here obj = getwithoutbinding(instance, name) - setattr(w_instance, name[2:], obj) + setattr(instance, name[2:], obj) else: space.setattr(w_instance, space.wrap(name[2:]), getattr(instance, name)) Modified: pypy/trunk/pypy/module/struct/test/test_struct.py ============================================================================== --- pypy/trunk/pypy/module/struct/test/test_struct.py (original) +++ pypy/trunk/pypy/module/struct/test/test_struct.py Thu Oct 30 16:33:38 2008 @@ -268,6 +268,7 @@ and PyPy might disagree on the specific exception raised in a specific situation, e.g. struct.error/TypeError/OverflowError. """ + import sys calcsize = self.struct.calcsize pack = self.struct.pack unpack = self.struct.unpack @@ -287,10 +288,8 @@ pack("0p") # bad '0p' in struct format except error: # (but ignored on CPython) pass - try: - unpack("0p", "") # bad '0p' in struct format - except error: # (but ignored on CPython) - pass + if '__pypy__' in sys.builtin_module_names: + raises(error, unpack, "0p", "") # segfaults on CPython 2.5.2! raises(error, pack, "b", 150) # argument out of range # XXX the accepted ranges still differs between PyPy and CPython @@ -330,6 +329,9 @@ just like the array module does. (This is actually used in the implementation of our interp-level array module.) """ + import sys + if '__pypy__' not in sys.builtin_module_names: + skip("PyPy extension") data = self.struct.pack("uuu", u'X', u'Y', u'Z') assert data == str(buffer(u'XYZ')) assert self.struct.unpack("uuu", data) == (u'X', u'Y', u'Z') From fijal at codespeak.net Thu Oct 30 16:44:04 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 16:44:04 +0100 (CET) Subject: [pypy-svn] r59573 - pypy/trunk/lib-python Message-ID: <20081030154404.4E18D169E0D@codespeak.net> Author: fijal Date: Thu Oct 30 16:44:02 2008 New Revision: 59573 Modified: pypy/trunk/lib-python/failure_list.txt Log: Update Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Thu Oct 30 16:44:02 2008 @@ -18,7 +18,6 @@ test_compile ! test_leading_newlines: impl detail; the rest: not good test_compiler ! unknown test_ctypes ! implementation details but also some real crashes -test_datetime ! the two test_negative_*() look like real bugs test_decimal missing decimal.ROUND_05UP test_descr arigo needs deciding what is impl details and what's not test_descrtut implementation detail only @@ -75,13 +74,12 @@ test_shelve ! unknown test_signal ! missing signal.alarm(), probably easy to add test_site ! fix me -test_socket ! uh? +test_socket ! some failures, look test_socketserver test skipped test_sort implementation detail test_sqlite ! why no sqlite available? test_startfile what is os.startfile? test_str arigo probably skip, investigate -test_string ! some failures, look deeper test_structmembers CPython-only test_subprocess ! missing resource.error. no clue about os.fpathconf(). test_syntax more small hacking here and there in the ast compiler @@ -107,7 +105,5 @@ test_with minor hacking in the ast compiler test_xml_etree_c import _elementtree test_xmlrpc sys.setdefaultencoding missing -test_zipfile ! see test_struct test_zipfile64 skipped test -test_zipimport many failures. the test itself seems not to run correctly From fijal at codespeak.net Thu Oct 30 16:47:55 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 16:47:55 +0100 (CET) Subject: [pypy-svn] r59574 - pypy/trunk/lib-python Message-ID: <20081030154755.00616169F4F@codespeak.net> Author: fijal Date: Thu Oct 30 16:47:55 2008 New Revision: 59574 Modified: pypy/trunk/lib-python/failure_list.txt Log: remove tests that pass Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Thu Oct 30 16:47:55 2008 @@ -29,12 +29,10 @@ test_email_codecs test skipped test_email_renamed ! same as test_email test_enumerate same as test_iterlen -test_exception_variations ! uh? test_file some more exceptions should be raised test_float float.__getformat__() exists mainly only for tests test_fork1 ! why did this fail just once? test_format test checking for exact exception messages -test_functools ! missing gc.collect(); some impl details; del p.__dict__? test_gc internal stuff, we may want to provide placeholders test_generators ! I really hate our bytecode compiler :-( test_genexps ! Fatal RPython error: InternalCompilerError :-( @@ -97,7 +95,6 @@ test_urllib2_localnet bogus test? test_urllib2net skipped test test_urllibnet skipped test -test_userstring ! unknown test_uu ! unknown test_wait3 no os.wait3() test_wait4 no os.wait4() From arigo at codespeak.net Thu Oct 30 17:19:40 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 17:19:40 +0100 (CET) Subject: [pypy-svn] r59575 - in pypy/trunk/pypy/interpreter: pyparser test Message-ID: <20081030161940.42AF3169F33@codespeak.net> Author: arigo Date: Thu Oct 30 17:19:39 2008 New Revision: 59575 Modified: pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py pypy/trunk/pypy/interpreter/test/test_syntax.py Log: (antocuni, arigo) Two tests and one fix for now: giving SyntaxError a non-completely-bogus .text attribute, in order to get non-completely-bogus tracebacks. Modified: pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py Thu Oct 30 17:19:39 2008 @@ -310,8 +310,9 @@ raise StopIteration tok, line, lnum, pos = self.token_stack[self.stack_pos] self.stack_pos += 1 - self._current_line = line - self._lineno = max(self._lineno, lnum) + if lnum > self._lineno: + self._current_line = line + self._lineno = lnum self._token_lnum = lnum self._offset = pos return tok Modified: pypy/trunk/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_syntax.py (original) +++ pypy/trunk/pypy/interpreter/test/test_syntax.py Thu Oct 30 17:19:39 2008 @@ -583,6 +583,35 @@ """ exec s +class AppTestSyntaxError: + + def test_grammar_error_location(self): + try: + exec """if 1: + class Foo: + bla + a b c d e + bar + """ + except SyntaxError, e: + assert e.lineno == 4 + assert e.text.endswith('a b c d e\n') + else: + raise Exception("no SyntaxError??") + + def test_astbuilder_error_location(self): + skip("in-progress") + program = "(1, 2) += (3, 4)\n" + try: + exec program + except SyntaxError, e: + assert e.lineno == 1 + assert e.text is None + assert e.offset is None + else: + raise Exception("no SyntaxError??") + + if __name__ == '__main__': # only to check on top of CPython (you need 2.4) from py.test import raises From arigo at codespeak.net Thu Oct 30 17:30:49 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 17:30:49 +0100 (CET) Subject: [pypy-svn] r59577 - in pypy/trunk/pypy/interpreter: pyparser test Message-ID: <20081030163049.9796D16850C@codespeak.net> Author: arigo Date: Thu Oct 30 17:30:46 2008 New Revision: 59577 Modified: pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py pypy/trunk/pypy/interpreter/pyparser/pythonparse.py pypy/trunk/pypy/interpreter/test/test_syntax.py Log: (antocuni, arigo) Improve the test, and according fix (and clean up a tiny bit). Modified: pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py Thu Oct 30 17:30:46 2008 @@ -298,32 +298,37 @@ self.input = strings tokens = generate_tokens( parser, strings, flags, keywords) self.token_stack = tokens - self._current_line = '' # the current line (as a string) - self._lineno = -1 self._token_lnum = 0 - self._offset = 0 self.stack_pos = 0 + self._stack_pos_max_seen = -1 def next(self): """Returns the next parsed token""" if self.stack_pos >= len(self.token_stack): raise StopIteration + if self.stack_pos > self._stack_pos_max_seen: + self._stack_pos_max_seen = self.stack_pos tok, line, lnum, pos = self.token_stack[self.stack_pos] self.stack_pos += 1 - if lnum > self._lineno: - self._current_line = line - self._lineno = lnum self._token_lnum = lnum - self._offset = pos return tok + def most_recent_token(self): + index = self._stack_pos_max_seen + if index >= 0: + return self.token_stack[index] + else: + return None, '', 0, 0 + def current_linesource(self): """Returns the current line being parsed""" - return self._current_line + tok, line, lnum, pos = self.most_recent_token() + return line def current_lineno(self): """Returns the current lineno""" - return self._lineno + tok, line, lnum, pos = self.most_recent_token() + return lnum def context(self): """Returns an opaque context object for later restore""" @@ -341,24 +346,8 @@ self.restore(ctx) return token - #### methods below have to be translated - def offset(self, ctx=None): - if ctx is None: - return self.stack_pos - else: - assert type(ctx) == int - return ctx - def get_pos(self): return self.stack_pos - def get_source_text(self, p0, p1): - "We get passed two token stack positions." - return "XXX this got left behind in a refactoring. Stack positions are %d and %d" % (p0, p1) - - def debug(self): - """return context for debug information""" - return (self._current_line, self._lineno) Source = PythonSource - Modified: pypy/trunk/pypy/interpreter/pyparser/pythonparse.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/pythonparse.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/pythonparse.py Thu Oct 30 17:30:46 2008 @@ -125,9 +125,8 @@ src = Source(self, lines, keywords, flags) if not target.match(src, builder): - line, lineno = src.debug() - # XXX needs better error messages - raise SyntaxError("invalid syntax", lineno, -1, line) + tok, line, lnum, pos = src.most_recent_token() + raise SyntaxError("invalid syntax", lnum, pos, line) # return None return builder Modified: pypy/trunk/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_syntax.py (original) +++ pypy/trunk/pypy/interpreter/test/test_syntax.py Thu Oct 30 17:30:46 2008 @@ -596,6 +596,7 @@ except SyntaxError, e: assert e.lineno == 4 assert e.text.endswith('a b c d e\n') + assert e.offset == e.text.index('b') + 1 else: raise Exception("no SyntaxError??") From arigo at codespeak.net Thu Oct 30 18:18:40 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 30 Oct 2008 18:18:40 +0100 (CET) Subject: [pypy-svn] r59579 - in pypy/trunk/pypy/interpreter: astcompiler pyparser test Message-ID: <20081030171840.B676B16A1CB@codespeak.net> Author: arigo Date: Thu Oct 30 18:18:40 2008 New Revision: 59579 Modified: pypy/trunk/pypy/interpreter/astcompiler/symbols.py pypy/trunk/pypy/interpreter/pyparser/astbuilder.py pypy/trunk/pypy/interpreter/pyparser/asthelper.py pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py pypy/trunk/pypy/interpreter/test/test_syntax.py Log: (antocuni, arigo) More tests, more fixes. Modified: pypy/trunk/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/symbols.py Thu Oct 30 18:18:40 2008 @@ -65,10 +65,10 @@ return prevrole def add_return(self, node): - raise SyntaxError("'return' outside function") + raise SyntaxError("'return' outside function", node.lineno) - def add_yield(self): - raise SyntaxError("'yield' outside function") + def add_yield(self, node): + raise SyntaxError("'yield' outside function", node.lineno) def DEBUG(self): print >> sys.stderr, self @@ -100,7 +100,7 @@ msg = self.parent.get_ambiguous_name_msg( "it contains a nested function using the " "variable '%s'" % (name,)) - raise SyntaxError(msg) + raise SyntaxError(msg) # XXX lineno!!!!!!!!!!!!!! if name in names_from_enclosing_funcs: enclosingscope = names_from_enclosing_funcs[name] if enclosingscope is None: @@ -111,7 +111,7 @@ msg = self.get_ambiguous_name_msg( "it is a nested function, so the origin of " "the variable '%s' is ambiguous" % (name,)) - raise SyntaxError(msg) + raise SyntaxError(msg) # XXX lineno!!!!!!!!!!!! enclosingscope.varscopes[name] = SC_CELL parent = self.parent while parent is not enclosingscope: @@ -223,7 +223,7 @@ name = self.mangle(name) if name in self.varroles: msg = "duplicate argument '%s' in function definition" % (name,) - raise SyntaxError(msg) + raise SyntaxError(msg) # XXX lineno!!!!!!!!!!!!!! self.varroles[name] = ROLE_PARAM def add_return(self, node): @@ -232,7 +232,7 @@ if self.return_with_arg is None: self.return_with_arg = node - def add_yield(self): + def add_yield(self, node): self.generator = True def export_names_to_children(self, names_from_enclosing_funcs, newnames): @@ -259,9 +259,11 @@ if self.bare_exec: raise SyntaxError("for CPython compatibility, an unqualified " "exec is not allowed here") + # XXX lineno!!!!!!!!!!!!!! if self.import_star: raise SyntaxError("for CPython compatibility, import * " "is not allowed here") + # XXX lineno!!!!!!!!!!!!!! def _is_nested_function(self): scope = self.parent @@ -493,7 +495,7 @@ prevrole = scope.add_global(name) if prevrole == ROLE_PARAM: msg = "name '%s' is a function parameter and declared global" - raise SyntaxError(msg % (name,)) + raise SyntaxError(msg % (name,), node.lineno) elif prevrole == ROLE_DEFINED: msg = "name '%s' is assigned to before global declaration" issue_warning(self.space, msg % (name,), @@ -562,7 +564,7 @@ def visitYield(self, node ): scope = self.cur_scope() - scope.add_yield() + scope.add_yield(node) node.value.accept( self ) def visitReturn(self, node): Modified: pypy/trunk/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/astbuilder.py Thu Oct 30 18:18:40 2008 @@ -326,8 +326,9 @@ assert l==3 lvalue = atoms[0] if isinstance(lvalue, ast.GenExpr) or isinstance(lvalue, ast.Tuple): - raise SyntaxError("augmented assign to tuple literal or generator expression not possible", - lineno, 0, "") + raise SyntaxError("augmented assign to tuple literal or " + "generator expression not possible", + lineno) assert isinstance(op, TokenObject) builder.push(ast.AugAssign(lvalue, op.get_name(), atoms[2], lineno)) @@ -859,8 +860,9 @@ token = tokens[-1] assert isinstance(token, TokenObject) # XXX if token.name == builder.parser.tokens['COMMA']: - raise SyntaxError, "trailing comma not allowed without" \ - "surrounding parentheses" + raise SyntaxError("trailing comma not allowed without " + "surrounding parentheses", + token.lineno, token.col) index = 0 l = len(tokens) @@ -1020,7 +1022,9 @@ token = atoms[index] assert isinstance(token, TokenObject) if token.get_value() != 'finally': - raise SyntaxError("Finally expected, got %s" % token.get_value()) + raise SyntaxError("Finally expected, got %s" % + token.get_value(), + token.lineno, token.col) body1 = ast.TryExcept(body, handlers, else_, atoms[0].lineno) res = ast.TryFinally(body1, atoms[index + 2], atoms[0].lineno) Modified: pypy/trunk/pypy/interpreter/pyparser/asthelper.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/asthelper.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/asthelper.py Thu Oct 30 18:18:40 2008 @@ -382,20 +382,20 @@ else: if isinstance(ast_node, ast.GenExpr): raise SyntaxError("assign to generator expression not possible", - lineno, 0, '') + lineno) elif isinstance(ast_node, ast.ListComp): raise SyntaxError("can't assign to list comprehension", - lineno, 0, '') + lineno) elif isinstance(ast_node, ast.CallFunc): if flags == consts.OP_DELETE: raise SyntaxError("can't delete function call", - lineno, 0, '') + lineno) else: raise SyntaxError("can't assign to function call", - lineno, 0, '') + lineno) else: raise SyntaxError("can't assign to non-lvalue", - lineno, 0, '') + lineno) def is_augassign( ast_node ): if ( isinstance( ast_node, ast.Name ) or Modified: pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/pythonlexer.py Thu Oct 30 18:18:40 2008 @@ -59,7 +59,8 @@ """Raised for lexer errors, e.g. when EOF is found prematurely""" def __init__(self, msg, line, strstart, token_stack): lineno, offset = strstart - SyntaxError.__init__(self, msg, lineno, offset, line) + # offset is zero-based here, but should be 1-based on the SyntaxError + SyntaxError.__init__(self, msg, lineno, offset + 1, line) self.token_stack = token_stack def generate_tokens( parser, lines, flags, keywords): Modified: pypy/trunk/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_syntax.py (original) +++ pypy/trunk/pypy/interpreter/test/test_syntax.py Thu Oct 30 18:18:40 2008 @@ -585,6 +585,17 @@ class AppTestSyntaxError: + def test_tokenizer_error_location(self): + line4 = "if ?: pass\n" + try: + exec "print\nprint\nprint\n" + line4 + except SyntaxError, e: + assert e.lineno == 4 + assert e.text == line4 + assert e.offset == e.text.index('?') + 1 + else: + raise Exception("no SyntaxError??") + def test_grammar_error_location(self): try: exec """if 1: @@ -601,14 +612,12 @@ raise Exception("no SyntaxError??") def test_astbuilder_error_location(self): - skip("in-progress") program = "(1, 2) += (3, 4)\n" try: exec program except SyntaxError, e: assert e.lineno == 1 assert e.text is None - assert e.offset is None else: raise Exception("no SyntaxError??") From fijal at codespeak.net Thu Oct 30 20:20:41 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 20:20:41 +0100 (CET) Subject: [pypy-svn] r59580 - pypy/build/benchmem Message-ID: <20081030192041.8694016A03F@codespeak.net> Author: fijal Date: Thu Oct 30 20:20:40 2008 New Revision: 59580 Modified: pypy/build/benchmem/smaps.py Log: Generalize a bit smaps - I don't use it for anything, but it's laying down in my wc and it's slightly better Modified: pypy/build/benchmem/smaps.py ============================================================================== --- pypy/build/benchmem/smaps.py (original) +++ pypy/build/benchmem/smaps.py Thu Oct 30 20:20:40 2008 @@ -2,6 +2,16 @@ import py import time +def append_attrs(self, attrs, headline): + attrs = attrs[:6] # not interested in "Referenced" + sizes = ",".join(map(str, attrs)) + assert sizes + self.stream.write("%-24s %s" %(sizes, headline)) + +def footer(self): + self.stream.write(self.SEPSNAPSHOT + "\n") + self.stream.flush() + class SmapsRecorder: SEPSNAPSHOT = "-"*80 @@ -11,13 +21,7 @@ self.smapspath = py.path.local("/proc/%d/smaps" %(pid,)) assert self.smapspath.check() - def snapshot(self): - def append_attrs(attrs): - attrs = attrs[:6] # not interested in "Referenced" - sizes = ",".join(map(str, attrs)) - assert sizes - self.stream.write("%-24s %s" %(sizes, headline)) - + def snapshot(self, appender=append_attrs, footer_writer=footer): f = self.smapspath.open() lines = f.readlines() f.close() @@ -37,13 +41,11 @@ break value = int(parts[1]) attrs.append(value) - append_attrs(attrs) + appender(self, attrs, headline) headline = nextheadline except StopIteration: - append_attrs(attrs) - self.stream.write(self.SEPSNAPSHOT + "\n") - self.stream.flush() - + appender(self, attrs, headline) + footer_writer(self) # # objects gained from reading of the logfile From fijal at codespeak.net Thu Oct 30 21:59:18 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 21:59:18 +0100 (CET) Subject: [pypy-svn] r59581 - pypy/build/benchmem Message-ID: <20081030205918.EE8EA16A092@codespeak.net> Author: fijal Date: Thu Oct 30 21:59:15 2008 New Revision: 59581 Modified: pypy/build/benchmem/report_graphic.py Log: some support for plotting graphs... intermediate check in Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Thu Oct 30 21:59:15 2008 @@ -4,20 +4,46 @@ import sys, py import smaps, runbench -from pylab import plot, show, title +from pylab import plot, show, title, bar, axes, xticks, legend, subplot, axis +import numpy + +HEAP = runbench.Mappings.HEAP +CODE = runbench.Mappings.CODE +DATA = runbench.Mappings.DATA + +def process_baseint_sizes(results): + lgt = len(results) + ind = [float(i)/lgt for i in range(lgt)] + heap_private = numpy.array([result.snapshot.filter(group=HEAP).private + for result in results]) + ip_code = numpy.array([result.snapshot.filter(group=result.executable, + kind=CODE). + private for result in results]) + ip_data = numpy.array([result.snapshot.filter(group=result.executable, + kind=DATA). + private for result in results]) + rest = numpy.array([result.snapshot.filter(group=result.executable, + inv=True). + filter(group=HEAP, inv=True).private for result in + results]) + bar(ind, heap_private, .1, color='r') + bar(ind, ip_code, .1, color='b', bottom=heap_private) + bar(ind, ip_data, .1, color='w', bottom=heap_private+ip_code) + bar(ind, rest, .1, color='black', bottom=heap_private+ip_code+ip_data) + show() def main(filename): resultset = runbench.ResultSet() - resultset.parse(py.path.local(filename), True) - # by default it shows all graphs, a bit boring, but educating ;) - for name, results in resultset.filter(benchtype="appprofiles").getname2results(): - for result in results: - lgt = len(result.snapshots) - x = [float(i)/lgt for i in range(lgt)] - y = [snapshot.private for snapshot in result.snapshots] - title(name) - plot(x, y) - show() + resultset.parse(py.path.local(filename)) + process_baseint_sizes(resultset.filter(benchtype="basesize").results) + #for name, results in resultset.filter(benchtype="appprofiles").getname2results(): + # for result in results: + # lgt = len(result.snapshots) + # x = [float(i)/lgt for i in range(lgt)] + # y = [snapshot.private for snapshot in result.snapshots] + # title(name) + # plot(x, y) + # show() if __name__ == '__main__': if len(sys.argv) > 3: From fijal at codespeak.net Thu Oct 30 22:30:33 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 22:30:33 +0100 (CET) Subject: [pypy-svn] r59582 - pypy/trunk/pypy/module/_codecs Message-ID: <20081030213033.198D0169E89@codespeak.net> Author: fijal Date: Thu Oct 30 22:30:31 2008 New Revision: 59582 Modified: pypy/trunk/pypy/module/_codecs/interp_codecs.py Log: this one is probably unnecessary Modified: pypy/trunk/pypy/module/_codecs/interp_codecs.py ============================================================================== --- pypy/trunk/pypy/module/_codecs/interp_codecs.py (original) +++ pypy/trunk/pypy/module/_codecs/interp_codecs.py Thu Oct 30 22:30:31 2008 @@ -60,7 +60,6 @@ one argument, the encoding name in all lower case letters, and return a tuple of functions (encoder, decoder, stream_reader, stream_writer). """ - #import pdb; pdb.set_trace() state = space.fromcache(CodecState) if space.is_true(space.callable(w_search_function)): state.codec_search_path.append(w_search_function) @@ -138,7 +137,6 @@ 'xmlcharrefreplace' as well as any other name registered with codecs.register_error that can handle ValueErrors. """ - #import pdb; pdb.set_trace() if w_encoding is None: encoding = space.sys.defaultencoding else: From fijal at codespeak.net Thu Oct 30 23:30:46 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 30 Oct 2008 23:30:46 +0100 (CET) Subject: [pypy-svn] r59583 - pypy/build/benchmem Message-ID: <20081030223046.34E6616A2D3@codespeak.net> Author: fijal Date: Thu Oct 30 23:30:41 2008 New Revision: 59583 Modified: pypy/build/benchmem/report_graphic.py Log: Progress, but slow. Now this *doesn't* show a picture, but saves to a file so people won't complain Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Thu Oct 30 23:30:41 2008 @@ -4,16 +4,17 @@ import sys, py import smaps, runbench -from pylab import plot, show, title, bar, axes, xticks, legend, subplot, axis +import pylab import numpy HEAP = runbench.Mappings.HEAP CODE = runbench.Mappings.CODE DATA = runbench.Mappings.DATA +BASE = '' def process_baseint_sizes(results): lgt = len(results) - ind = [float(i)/lgt for i in range(lgt)] + ind = numpy.array([float(i)/lgt for i in range(lgt)]) heap_private = numpy.array([result.snapshot.filter(group=HEAP).private for result in results]) ip_code = numpy.array([result.snapshot.filter(group=result.executable, @@ -26,16 +27,28 @@ inv=True). filter(group=HEAP, inv=True).private for result in results]) - bar(ind, heap_private, .1, color='r') - bar(ind, ip_code, .1, color='b', bottom=heap_private) - bar(ind, ip_data, .1, color='w', bottom=heap_private+ip_code) - bar(ind, rest, .1, color='black', bottom=heap_private+ip_code+ip_data) - show() + # XXX add axes scaling + WIDTH = .1 + p0 = pylab.bar(ind, heap_private, WIDTH, color='r') + p1 = pylab.bar(ind, ip_code, WIDTH, color='b', bottom=heap_private) + p2 = pylab.bar(ind, ip_data, WIDTH, color='w', bottom=heap_private+ip_code) + p3 = pylab.bar(ind, rest, WIDTH, color='black', + bottom=heap_private+ip_code+ip_data) + pylab.xticks(ind + WIDTH/2, [result.executable for result in results]) + pylab.legend([p0[0], p1[0], p2[0], p3[0]], + ['heap private', 'ip code', 'ip data', 'rest']) + pylab.savefig(BASE + "base_size.ps") + return ip_code + ip_data + heap_private + rest + +#def process_objsizes(results): +# for name, result in xxxx def main(filename): resultset = runbench.ResultSet() resultset.parse(py.path.local(filename)) - process_baseint_sizes(resultset.filter(benchtype="basesize").results) + totals = process_baseint_sizes(resultset.filter(benchtype="basesize"). + results) +# process_objsizes(resultset.filter(benchtype="objsize").results) #for name, results in resultset.filter(benchtype="appprofiles").getname2results(): # for result in results: # lgt = len(result.snapshots) From xoraxax at codespeak.net Fri Oct 31 00:32:21 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 31 Oct 2008 00:32:21 +0100 (CET) Subject: [pypy-svn] r59585 - pypy/build/benchmem Message-ID: <20081030233221.7999C16A15B@codespeak.net> Author: xoraxax Date: Fri Oct 31 00:32:17 2008 New Revision: 59585 Modified: pypy/build/benchmem/report.py Log: Added some comments after some discussion between Maciej and me (dirty seems to mean "different than in the backing store"). Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Fri Oct 31 00:32:17 2008 @@ -183,16 +183,24 @@ result.snapshot.filter(group=HEAP).private_clean) makerow("HEAP-private_dirty", lambda result: result.snapshot.filter(group=HEAP).private_dirty) + # we only show the clean bits of the code, this might not really work + # out if the code is not compiled position-indepently, likewise the often + # seen dirty code page might be a dispatch table (correct term?) of the linker makerow("IP-CODE-shared_clean", lambda result: result.snapshot.filter(group=result.executable, kind=CODE).shared_clean) makerow("IP-CODE-private_clean", lambda result: result.snapshot.filter(group=result.executable, kind=CODE).private_clean) + # whole static data of the process in memory, also including e.g. shared data with other processes makerow("IP-DATA-RSS", lambda result: result.snapshot.filter(group=result.executable, kind=DATA).rss) + # static data that is not shared with another process and was not modified by the process + # can be easily shared with another process makerow("IP-DATA-private_clean", lambda result: result.snapshot.filter(group=result.executable, kind=DATA).private_clean) + # static data that is not shared with another process and was modified by the process makerow("IP-DATA-private_dirty", lambda result: result.snapshot.filter(group=result.executable, kind=DATA).private_dirty) + # rest includes other shared libraries that are neither the interpreter nor the heap makerow("REST-private_clean", lambda result: result.snapshot.filter(group=result.executable, inv=True). filter(group=HEAP, inv=True).private_clean) From fijal at codespeak.net Fri Oct 31 00:57:55 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 31 Oct 2008 00:57:55 +0100 (CET) Subject: [pypy-svn] r59586 - pypy/build/benchmem Message-ID: <20081030235755.249DC16A2CA@codespeak.net> Author: fijal Date: Fri Oct 31 00:57:54 2008 New Revision: 59586 Modified: pypy/build/benchmem/report_graphic.py Log: More support for drawing graphs (I think this is it for today) Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Fri Oct 31 00:57:54 2008 @@ -11,6 +11,7 @@ CODE = runbench.Mappings.CODE DATA = runbench.Mappings.DATA BASE = '' +SHOW = False def process_baseint_sizes(results): lgt = len(results) @@ -27,6 +28,9 @@ inv=True). filter(group=HEAP, inv=True).private for result in results]) + return plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results) + +def plot_basint_sizes(heap_private, ip_code, ip_data, rest, results): # XXX add axes scaling WIDTH = .1 p0 = pylab.bar(ind, heap_private, WIDTH, color='r') @@ -38,25 +42,65 @@ pylab.legend([p0[0], p1[0], p2[0], p3[0]], ['heap private', 'ip code', 'ip data', 'rest']) pylab.savefig(BASE + "base_size.ps") + if SHOW: + pylab.show() return ip_code + ip_data + heap_private + rest -#def process_objsizes(results): -# for name, result in xxxx +def process_objsizes(resultset): + def incremental_private(result): + return (result.snapshots[1].heap_private() - + result.snapshots[0].heap_private()) + + names = [name for name, _ in resultset.getname2results()] + results = resultset.getname2results() + benchresults = [[] for _ in range(len(results[0]))] + executables = [result.executable for result in results[0][1]] + for _, results in results: + for i, result in enumerate(results): + benchresults[i].append(incremental_private(result)) + plot_objsizes(benchresults, names, executables) -def main(filename): - resultset = runbench.ResultSet() - resultset.parse(py.path.local(filename)) - totals = process_baseint_sizes(resultset.filter(benchtype="basesize"). - results) -# process_objsizes(resultset.filter(benchtype="objsize").results) + +def plot_objsizes(benchresults, names, executables): + # XXX implement saner colorization + colors = ['r', 'g', 'b', 'black', 'white', 'cyan', 'magenta', 'yellow' + 'purple', 'grey'] + lgt = len(benchresults[0]) + baseindices = numpy.array([float(i)/lgt for i in range(lgt)]) + basewidth = (baseindices[1] - baseindices[0]) + skip = (basewidth * .5) / len(benchresults) + bars = [] + for i, benchresult in enumerate(benchresults): + bars.append(pylab.bar(baseindices + skip * i, benchresult, skip, + color=colors[i])) + # XXX I'm completely unsure how to make a reasonable + pylab.legend([bar[0] for bar in bars], executables) + pylab.savefig(BASE + "objsizes.ps") + if SHOW: + pylab.show() + +def process_appprofiles(resultset, totals): + pass #for name, results in resultset.filter(benchtype="appprofiles").getname2results(): # for result in results: # lgt = len(result.snapshots) # x = [float(i)/lgt for i in range(lgt)] # y = [snapshot.private for snapshot in result.snapshots] - # title(name) - # plot(x, y) - # show() + # pylab.title(name) + # pylab.plot(x, y) + # + # if SHOW: + # pylab.show() + + +def main(filename): + resultset = runbench.ResultSet() + resultset.parse(py.path.local(filename)) + totals = process_baseint_sizes(resultset.filter(benchtype="basesize"). + results) + process_objsizes(resultset.filter(benchtype="objsizes")) + process_appprofiles(resultset.filter(benchtype="appprofiles"), + totals) if __name__ == '__main__': if len(sys.argv) > 3: From fijal at codespeak.net Fri Oct 31 12:31:20 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 31 Oct 2008 12:31:20 +0100 (CET) Subject: [pypy-svn] r59588 - pypy/build/benchmem Message-ID: <20081031113120.9C4CF16A2FE@codespeak.net> Author: fijal Date: Fri Oct 31 12:31:18 2008 New Revision: 59588 Modified: pypy/build/benchmem/report_graphic.py Log: A bit more progress on drawing graphs Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Fri Oct 31 12:31:18 2008 @@ -14,8 +14,15 @@ SHOW = False def process_baseint_sizes(results): - lgt = len(results) - ind = numpy.array([float(i)/lgt for i in range(lgt)]) + """ This function plots base interpreter sizes of various interpreters + with bars specifying: + + * heap private + * ip code + * ip data + * private rest + """ + heap_private = numpy.array([result.snapshot.filter(group=HEAP).private for result in results]) ip_code = numpy.array([result.snapshot.filter(group=result.executable, @@ -30,9 +37,12 @@ results]) return plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results) -def plot_basint_sizes(heap_private, ip_code, ip_data, rest, results): +def plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results): # XXX add axes scaling + pylab.clf() WIDTH = .1 + lgt = len(results) + ind = numpy.array([float(i)/lgt for i in range(lgt)]) p0 = pylab.bar(ind, heap_private, WIDTH, color='r') p1 = pylab.bar(ind, ip_code, WIDTH, color='b', bottom=heap_private) p2 = pylab.bar(ind, ip_data, WIDTH, color='w', bottom=heap_private+ip_code) @@ -44,9 +54,17 @@ pylab.savefig(BASE + "base_size.ps") if SHOW: pylab.show() - return ip_code + ip_data + heap_private + rest + res = {} + for i, value in enumerate(ip_code + ip_data + heap_private + rest): + res[results[i].executable] = value + return res def process_objsizes(resultset): + """ This function creates series of graphs for showing incremental + private memory consumed for object allocation (without base interpreter + size) + """ + def incremental_private(result): return (result.snapshots[1].heap_private() - result.snapshots[0].heap_private()) @@ -65,32 +83,55 @@ # XXX implement saner colorization colors = ['r', 'g', 'b', 'black', 'white', 'cyan', 'magenta', 'yellow' 'purple', 'grey'] - lgt = len(benchresults[0]) - baseindices = numpy.array([float(i)/lgt for i in range(lgt)]) - basewidth = (baseindices[1] - baseindices[0]) - skip = (basewidth * .5) / len(benchresults) - bars = [] - for i, benchresult in enumerate(benchresults): - bars.append(pylab.bar(baseindices + skip * i, benchresult, skip, - color=colors[i])) - # XXX I'm completely unsure how to make a reasonable - pylab.legend([bar[0] for bar in bars], executables) - pylab.savefig(BASE + "objsizes.ps") - if SHOW: - pylab.show() + + benchresults = numpy.array(benchresults) + names = numpy.array(names) + + split = 10 # max number of bars per graph + for view in range(len(benchresults[0])/split): + start = view * split + end = min((view + 1)*split, len(benchresults[0])) + results = benchresults[:, start:end] + pylab.clf() + lgt = len(results[0]) + baseindices = numpy.array([float(i)/lgt for i in range(lgt)]) + basewidth = (baseindices[1] - baseindices[0]) + skip = (basewidth * .5) / len(benchresults) + bars = [] + for i, benchresult in enumerate(results): + bars.append(pylab.bar(baseindices + skip * i, benchresult, skip, + color=colors[i])) + pylab.legend([bar[0] for bar in bars], executables) + # XXX a lot of magic is required to provide a reasonable + # set of non-overlapping xticks + pylab.xticks(baseindices + basewidth/4, ['B%d' % i for i in + range(start, end)]) + pylab.savefig(BASE + "objsizes_%d.ps" % view) + if SHOW: + pylab.show() def process_appprofiles(resultset, totals): - pass - #for name, results in resultset.filter(benchtype="appprofiles").getname2results(): - # for result in results: - # lgt = len(result.snapshots) - # x = [float(i)/lgt for i in range(lgt)] - # y = [snapshot.private for snapshot in result.snapshots] - # pylab.title(name) - # pylab.plot(x, y) - # - # if SHOW: - # pylab.show() + """ This function plots incremental memory consumption of app benchmarks + (withou interpreter size) versus time (in %s) + """ + + pylab.clf() + for name, results in resultset.filter(benchtype="appprofiles").getname2results(): + plots = [] + for result in results: + lgt = len(result.snapshots) + x = [(float(i)/lgt)*100 for i in range(lgt)] + y = [snapshot.private - totals[result.executable] + for snapshot in result.snapshots] + pylab.title(name) + plots.append(pylab.plot(x, y)) + + pylab.legend(plots, [result.executable for result in results]) + pylab.xlabel("time (%)") + pylab.ylabel("incremental private memory consumption") + pylab.savefig(BASE + 'appprofiles_%s.ps' % name) + if SHOW: + pylab.show() def main(filename): From fijal at codespeak.net Fri Oct 31 14:26:21 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 31 Oct 2008 14:26:21 +0100 (CET) Subject: [pypy-svn] r59589 - pypy/trunk/lib-python/modified-2.5.2 Message-ID: <20081031132621.1571E16A299@codespeak.net> Author: fijal Date: Fri Oct 31 14:26:19 2008 New Revision: 59589 Added: pypy/trunk/lib-python/modified-2.5.2/ihooks.py - copied, changed from r59572, pypy/trunk/lib-python/2.5.2/ihooks.py Log: Add a modified ihooks, which actually accepts the same number of parameters as default __import__ Copied: pypy/trunk/lib-python/modified-2.5.2/ihooks.py (from r59572, pypy/trunk/lib-python/2.5.2/ihooks.py) ============================================================================== --- pypy/trunk/lib-python/2.5.2/ihooks.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/ihooks.py Fri Oct 31 14:26:19 2008 @@ -357,7 +357,8 @@ def set_hooks(self, hooks): return self.loader.set_hooks(hooks) - def import_module(self, name, globals={}, locals={}, fromlist=[]): + def import_module(self, name, globals={}, locals={}, fromlist=[], + level=-1): name = str(name) if name in self.modules: return self.modules[name] # Fast path @@ -399,7 +400,8 @@ """A module importer that supports packages.""" - def import_module(self, name, globals=None, locals=None, fromlist=None): + def import_module(self, name, globals=None, locals=None, fromlist=None, + level=-1): parent = self.determine_parent(globals) q, tail = self.find_head_package(parent, str(name)) m = self.load_tail(q, tail) From arigo at codespeak.net Fri Oct 31 14:48:09 2008 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 31 Oct 2008 14:48:09 +0100 (CET) Subject: [pypy-svn] r59594 - pypy/trunk/lib-python Message-ID: <20081031134809.1450016A2E7@codespeak.net> Author: arigo Date: Fri Oct 31 14:48:08 2008 New Revision: 59594 Modified: pypy/trunk/lib-python/failure_list.txt Log: test_descr passes. Modified: pypy/trunk/lib-python/failure_list.txt ============================================================================== --- pypy/trunk/lib-python/failure_list.txt (original) +++ pypy/trunk/lib-python/failure_list.txt Fri Oct 31 14:48:08 2008 @@ -19,7 +19,6 @@ test_compiler ! unknown test_ctypes ! implementation details but also some real crashes test_decimal missing decimal.ROUND_05UP -test_descr arigo needs deciding what is impl details and what's not test_descrtut implementation detail only test_dis probably not worth the pain of whacking at the compiler test_distutils this is our issue367 From antocuni at codespeak.net Fri Oct 31 14:49:49 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 31 Oct 2008 14:49:49 +0100 (CET) Subject: [pypy-svn] r59595 - in pypy/branch/oo-jit/pypy: jit/codegen/cli jit/codegen/cli/test translator/cli/src Message-ID: <20081031134949.0161A16A30D@codespeak.net> Author: antocuni Date: Fri Oct 31 14:49:49 2008 New Revision: 59595 Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Log: yaih!!! All promotion tests pass! :-) Now flexswitches are supported both on ints and objects; to do so, we need to duplicate a bit of code, because .NET generics are not good enough for our needs. Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Fri Oct 31 14:49:49 2008 @@ -1,3 +1,4 @@ +import py from pypy.tool.pairtype import extendabletype from pypy.rlib.rarithmetic import intmask from pypy.rpython.ootypesystem import ootype @@ -17,7 +18,8 @@ from pypy.translator.cli import dotnet System = CLR.System DelegateHolder = CLR.pypy.runtime.DelegateHolder -LowLevelFlexSwitch = CLR.pypy.runtime.LowLevelFlexSwitch +IntLowLevelFlexSwitch = CLR.pypy.runtime.IntLowLevelFlexSwitch +ObjectLowLevelFlexSwitch = CLR.pypy.runtime.ObjectLowLevelFlexSwitch FlexSwitchCase = CLR.pypy.runtime.FlexSwitchCase MethodIdMap = CLR.pypy.runtime.MethodIdMap OpCodes = System.Reflection.Emit.OpCodes @@ -689,16 +691,16 @@ class FlexCaseMethod(MethodGenerator): flexswitch = None - value = -1 + gv_value = None linkargs_gv = None linkargs_gv_map = None def setup_flexswitches(self): pass - def set_parent_flexswitch(self, flexswitch, value): + def set_parent_flexswitch(self, flexswitch, gv_value): self.parent_flexswitch = flexswitch - self.value = value + self.gv_value = gv_value self.setup_dispatch_block() def set_linkargs_gv(self, linkargs_gv): @@ -719,7 +721,7 @@ MethodGenerator.emit_code(self) func = self.gv_entrypoint.holder.GetFunc() func2 = clidowncast(func, FlexSwitchCase) - self.parent_flexswitch.llflexswitch.add_case(self.value, func2) + self.parent_flexswitch.set_link(self.gv_value, func2) self.graphinfo.register_case(self.method_id, func2) def emit_preamble(self): @@ -888,14 +890,17 @@ return self._jump_if(gv_condition, OpCodes.Brtrue) def flexswitch(self, gv_exitswitch, args_gv): - # XXX: this code is valid only for MainMethod self.meth.setup_flexswitches() - flexswitch = IntFlexSwitch(self.meth, args_gv) + clitype = gv_exitswitch.getCliType() + if clitype.get_IsPrimitive(): + flexswitch = IntFlexSwitch(self.meth, args_gv) + else: + flexswitch = ObjectFlexSwitch(self.meth, args_gv) gv_flexswitch = flexswitch.gv_flexswitch default_branch = self.meth.newbranch() label = default_branch.enter_next_block(args_gv) - flexswitch.llflexswitch.set_default_blockid(label.block_id) + flexswitch.set_defaul_link(label) op = ops.DoFlexSwitch(self.meth, gv_flexswitch, gv_exitswitch, args_gv) self.appendop(op) @@ -915,8 +920,8 @@ for op in self.operations: op.emit() - -class IntFlexSwitch(CodeGenSwitch): +template = """ +class %(classname)s(CodeGenSwitch): def __init__(self, graph, linkargs_gv): self.graph = graph @@ -925,6 +930,13 @@ obj = dotnet.cliupcast(self.llflexswitch, System.Object) self.gv_flexswitch = NativeObjectConst(obj) + def set_defaul_link(self, label): + self.llflexswitch.set_default_blockid(label.block_id) + + def set_link(self, gv_value, func): + value = revealconst(gv_value) + self.llflexswitch.add_case(value, func) + def add_case(self, gv_case): graph = self.graph name = graph.name + '_case' @@ -934,10 +946,34 @@ graphinfo = graph.graphinfo meth = FlexCaseMethod(graph.rgenop, name, restype, arglist, delegatetype, graphinfo) - value = gv_case.revealconst(ootype.Signed) - meth.set_parent_flexswitch(self, value) + meth.set_parent_flexswitch(self, gv_case) meth.set_linkargs_gv(self.linkargs_gv) return meth.branches[0] +""" + +def revealconst_int(gv_value): + return gv_value.revealconst(ootype.Signed) + +def revealconst_obj(gv_value): + obj = gv_value.revealconst(ootype.Object) + return dotnet.cast_to_native_object(obj) + +def build_flexswitch_class(classname, LowLevelFlexSwitch, revealconst): + src = py.code.Source(template % locals()) + mydict = globals().copy() + mydict['LowLevelFlexSwitch'] = LowLevelFlexSwitch + mydict['revealconst'] = revealconst + exec src.compile() in mydict + globals()[classname] = mydict[classname] + +build_flexswitch_class('IntFlexSwitch', + IntLowLevelFlexSwitch, + revealconst_int) + +build_flexswitch_class('ObjectFlexSwitch', + ObjectLowLevelFlexSwitch, + revealconst_obj) + global_rgenop = RCliGenOp() RCliGenOp.constPrebuiltGlobal = global_rgenop.genconst Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py (original) +++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_promotion.py Fri Oct 31 14:49:49 2008 @@ -7,9 +7,4 @@ # for the individual tests see # ====> ../../../rainbow/test/test_promotion.py - def skip(self): - py.test.skip('in progress') - - test_promote_class = skip - test_promote_class_vstruct = skip - test_read___class___after_promotion = skip + pass Modified: pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Fri Oct 31 14:49:49 2008 @@ -132,6 +132,9 @@ public delegate uint FlexSwitchCase(uint block, InputArgs args); + // XXX: there is a lot of code duplication between the next three classes, + // but it's hard to share the code in a way that it's both efficient and + // supported by gencli public class MethodIdMap { public FlexSwitchCase[] cases = new FlexSwitchCase[4]; @@ -158,23 +161,26 @@ } } - public class LowLevelFlexSwitch + public class BaseLowLevelFlexSwitch { public uint default_blockid = 0xFFFFFFFF; - public int numcases = 0; - public int[] values = new int[4]; - public FlexSwitchCase[] cases = new FlexSwitchCase[4]; - public void set_default_blockid(uint blockid) { this.default_blockid = blockid; } + } - public void add_case(int v, FlexSwitchCase c) + public class IntLowLevelFlexSwitch: BaseLowLevelFlexSwitch + { + public int numcases = 0; + public int[] values = new int[4]; + public FlexSwitchCase[] cases = new FlexSwitchCase[4]; + + public void add_case(int value, FlexSwitchCase c) { if (numcases >= values.Length) grow(); - values[numcases] = v; + values[numcases] = value; cases[numcases] = c; numcases++; } @@ -191,10 +197,10 @@ cases = newcases; } - public uint execute(int v, InputArgs args) + public uint execute(int value, InputArgs args) { for(int i=0; i= values.Length) + grow(); + values[numcases] = value; + cases[numcases] = c; + numcases++; + } + + private void grow() + { + int newsize = values.Length * 2; + object[] newvalues = new object[newsize]; + Array.Copy(values, newvalues, values.Length); + values = newvalues; + + FlexSwitchCase[] newcases = new FlexSwitchCase[newsize]; + Array.Copy(cases, newcases, cases.Length); + cases = newcases; + } + + public uint execute(object value, InputArgs args) + { + for(int i=0; i Author: antocuni Date: Fri Oct 31 14:55:46 2008 New Revision: 59596 Removed: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_gencli_ts.py Log: delete outdated test From antocuni at codespeak.net Fri Oct 31 16:28:57 2008 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 31 Oct 2008 16:28:57 +0100 (CET) Subject: [pypy-svn] r59600 - in pypy/branch/oo-jit/pypy/jit: rainbow tl Message-ID: <20081031152857.67F7E16A258@codespeak.net> Author: antocuni Date: Fri Oct 31 16:28:56 2008 New Revision: 59600 Added: pypy/branch/oo-jit/pypy/jit/tl/targettlc.py (contents, props changed) Modified: pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py pypy/branch/oo-jit/pypy/jit/tl/tlc.py Log: - rpython fix for the rainbow interpreter - add a target to translate tlc into a standalone interpreter, which also translates with JIT to CLI, with good results Modified: pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py (original) +++ pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py Fri Oct 31 16:28:56 2008 @@ -1112,7 +1112,9 @@ return rtimeshift.geninstanceof(self.jitstate, objbox, typedesc) # else it's a vstruct - objtypedesc = objbox.content.typedesc + content = objbox.content + assert isinstance(content, rcontainer.VirtualStruct) + objtypedesc = content.typedesc result = objtypedesc.issubtype(typedesc) return rvalue.ll_fromvalue(self.jitstate, result) Added: pypy/branch/oo-jit/pypy/jit/tl/targettlc.py ============================================================================== --- (empty file) +++ pypy/branch/oo-jit/pypy/jit/tl/targettlc.py Fri Oct 31 16:28:56 2008 @@ -0,0 +1,51 @@ +import py +py.magic.autopath() +from pypy.jit.tl.tlc import interp, interp_eval +from pypy.jit.codegen.hlinfo import highleveljitinfo + + +def entry_point(args): + """Main entry point of the stand-alone executable: + takes a list of strings and returns the exit code. + """ + # store args[0] in a place where the JIT log can find it (used by + # viewcode.py to know the executable whose symbols it should display) + highleveljitinfo.sys_executable = args[0] + if len(args) < 3: + print "Usage: %s filename x" % (args[0],) + return 2 + filename = args[1] + x = int(args[2]) + bytecode = load_bytecode(filename) + res = interp(bytecode, inputarg=x) + print res + return 0 + +def load_bytecode(filename): + from pypy.rlib.streamio import open_file_as_stream + f = open_file_as_stream(filename) + bytecode = f.readall() + f.close() + return bytecode + +def target(driver, args): + return entry_point, None + +# ____________________________________________________________ + +from pypy.jit.hintannotator.policy import HintAnnotatorPolicy + +class MyHintAnnotatorPolicy(HintAnnotatorPolicy): + novirtualcontainer = True + oopspec = True + +def portal(driver): + """Return the 'portal' function, and the hint-annotator policy. + The portal is the function that gets patched with a call to the JIT + compiler. + """ + return interp_eval, MyHintAnnotatorPolicy() + +if __name__ == '__main__': + import sys + sys.exit(entry_point(sys.argv)) Modified: pypy/branch/oo-jit/pypy/jit/tl/tlc.py ============================================================================== --- pypy/branch/oo-jit/pypy/jit/tl/tlc.py (original) +++ pypy/branch/oo-jit/pypy/jit/tl/tlc.py Fri Oct 31 16:28:56 2008 @@ -1,5 +1,6 @@ '''Toy Language with Cons Cells''' +import autopath import py from pypy.jit.tl.tlopcode import * from pypy.jit.tl import tlopcode @@ -240,7 +241,7 @@ elif opcode == BR_COND: cond = stack.pop() - hint(cond.__class__, promote=True) + hint(cond, promote_class=True) if cond.t(): pc += char2int(code[pc]) pc += 1 @@ -272,3 +273,12 @@ interp , interp_eval = make_interp(supports_call = True) interp_without_call, interp_eval_without_call = make_interp(supports_call = False) + +if __name__ == '__main__': + import sys + from pypy.jit.tl.test.test_tl import FACTORIAL_SOURCE + bytecode = compile(FACTORIAL_SOURCE) + if len(sys.argv) >= 2 and sys.argv[1] == 'assemble': + print bytecode + else: + print ','.join([str(ord(n)) for n in bytecode]) From hpk at codespeak.net Fri Oct 31 18:52:28 2008 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 31 Oct 2008 18:52:28 +0100 (CET) Subject: [pypy-svn] r59601 - pypy/trunk/pypy/doc Message-ID: <20081031175228.7A9C216A396@codespeak.net> Author: hpk Date: Fri Oct 31 18:52:25 2008 New Revision: 59601 Modified: pypy/trunk/pypy/doc/maemo.txt Log: some ReST fixes, mention chinook. Modified: pypy/trunk/pypy/doc/maemo.txt ============================================================================== --- pypy/trunk/pypy/doc/maemo.txt (original) +++ pypy/trunk/pypy/doc/maemo.txt Fri Oct 31 18:52:25 2008 @@ -6,18 +6,11 @@ the Maemo_ platform. This howto should work well for getting a usable Python Interpreter for Nokia's N810_ device. -.. _N810: http://en.wikipedia.org/wiki/Nokia_N810 -.. _`Internet-Tablet-OS`: http://en.wikipedia.org/wiki/Internet_Tablet_OS -.. _Maemo: http://www.maemo.org -.. _Scratchbox: http://www.scratchbox.org -.. _`INSTALL.txt`: http://tablets-dev.nokia.com/4.1/INSTALL.txt - setup cross-compilation environment ------------------------------------- -The main steps are to install scratchbox and the Maemo SDK. Most of the -information from this section is taken from Nokia's `INSTALL.txt`_ which -provides more detail. +The main steps are to install scratchbox and the Maemo SDK. Please refer +to Nokia's `INSTALL.txt`_ for more detail. Adjust linux kernel settings +++++++++++++++++++++++++++++++++ @@ -25,7 +18,7 @@ In order to install and run scratchbox you will need to adjust your Linux kernel settings. Note that the VDSO setting may crash your computer - if that is the case, try running without -this setting. +this setting. You can try it like this:: $ echo 4096 | sudo tee /proc/sys/vm/mmap_min_addr $ echo 0 | sudo tee /proc/sys/vm/vdso_enabled @@ -49,11 +42,12 @@ The script will automatically download Debian packages or tarballs and pre-configure a scratchbox environment with so called "devkits" -and "toolchains" for performing cross-compilation. +and "toolchains" for performing cross-compilation. It's fine +and recommended to use your linux account name as a scratchbox +ACCOUNTNAME. -It also sets up an "sbox" group on your system and makes the -the user "ACCOUNTNAME" a member of that group. Members of the group -have the right to log into a scratchbox environment. +It also sets up an "sbox" group on your system and makes you +a member - giving the right to login to a scratchbox environment. testing that scratchbox environment works +++++++++++++++++++++++++++++++++++++++++++++++ @@ -67,8 +61,8 @@ target" because we have not yet created a cross-compilation target. -Note that Scratchbox starts services in the background -which can be started and stopped via:: +Note that Scratchbox starts daemon services which +can be controlled via:: /scratchbox/sbin/sbox_ctl start|stop @@ -109,11 +103,16 @@ 1. Go into your scratchbox by executing ``/scratchbox/login`` (this should bring you to a shell with the DIABLO_ARMEL target) -2. Add these lines to ``/etc/apt/sources.list`` +2. Add these lines to ``/etc/apt/sources.list``:: deb http://repository.maemo.org/extras/ diablo free non-free deb http://repository.maemo.org/extras-devel/ diablo free non-free + NOTE: if you have an older version of Maemo on your device you + can try substitute "chinook" for "diablo" in the above lines + and/or update your firmware. You can probably see which version + you are using by looking at the other content of the ``sources.list``. + 3. Perform ``apt-get update``. 4. Install some neccessary packages:: @@ -142,7 +141,7 @@ python translate.py --platform=maemo --opt=mem -This will last a some 30-60 minutes on most machines. For compiling +This will last some 30-60 minutes on most machines. For compiling the C source code PyPy's tool chain will use our scratchbox/Maemo cross-compilation environment. @@ -165,5 +164,10 @@ Start ``pypy-c`` on the device. +.. _N810: http://en.wikipedia.org/wiki/Nokia_N810 +.. _`Internet-Tablet-OS`: http://en.wikipedia.org/wiki/Internet_Tablet_OS +.. _Maemo: http://www.maemo.org +.. _Scratchbox: http://www.scratchbox.org +.. _`INSTALL.txt`: http://tablets-dev.nokia.com/4.1/INSTALL.txt From xoraxax at codespeak.net Fri Oct 31 19:11:11 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 31 Oct 2008 19:11:11 +0100 (CET) Subject: [pypy-svn] r59602 - in pypy/build/benchmem: . testing Message-ID: <20081031181111.D9E7916A38B@codespeak.net> Author: xoraxax Date: Fri Oct 31 19:11:11 2008 New Revision: 59602 Modified: pypy/build/benchmem/runbench.py pypy/build/benchmem/testing/test_benchtool.py Log: Added snapshot headers and timestamps. Modified: pypy/build/benchmem/runbench.py ============================================================================== --- pypy/build/benchmem/runbench.py (original) +++ pypy/build/benchmem/runbench.py Fri Oct 31 19:11:11 2008 @@ -20,6 +20,7 @@ class BenchRunner: SEPBENCH = "=" * 80 + HEADERSEP = "HEADER" def __init__(self, executable, logpath, options): self.executable = executable @@ -47,6 +48,12 @@ print >>self.logstream, "#benchargs=%s" %(args,) print >>self.logstream + def write_internal_header(self, kw): + print >>self.logstream, self.HEADERSEP + for name, value in kw.items(): + print >>self.logstream, "#%s=%s" % (name, value) + print >>self.logstream + def log(self, *args): print " ".join(map(str, args)) @@ -225,6 +232,7 @@ def interact_with_child(self, rec, stdin, stdout): while not stdin.closed: try: + self.write_internal_header({"TS": str(time.time())}) rec.snapshot() except py.error.ENOENT: break @@ -268,6 +276,22 @@ # ================ reading a benchmark log file ======================= # +def parseheader(stream_iter): + kw = {} + for lineno, line in stream_iter: + if not line.strip(): + return kw + assert line.startswith("#"), line + key, value = map(str.strip, line[1:].split("=")) + kw[key] = value + + +def parse_result(stream, kw, private_only): + benchtype = kw.pop('benchtype') + chosen_cls = benchtype2class[benchtype] + return chosen_cls.parse(stream, kw, private_only) + + class ResultSet(object): def __init__(self, results=None): if results is None: @@ -296,15 +320,6 @@ self.results.extend(self.yield_results(f, private_only)) f.close() - def parseheader(self, stream_iter): - kw = {} - for lineno, line in stream_iter: - if not line.strip(): - return kw - assert line.startswith("#"), line - key, value = map(str.strip, line[1:].split("=")) - kw[key] = value - def yield_results(self, stream, private_only): stream_iter = enumerate(stream) for lineno, line in stream_iter: @@ -314,32 +329,32 @@ else: break while 1: - kw = self.parseheader(stream_iter) + kw = parseheader(stream_iter) if kw is None: break yield parse_result(stream_iter, kw, private_only) -def parse_result(stream, kw, private_only): - benchtype = kw.pop('benchtype') - chosen_cls = benchtype2class[benchtype] - return chosen_cls.parse(stream, kw, private_only) - class Result(object): @classmethod def parse(cls, lnstream, kw, private_only): snapshots = [] mappings = [] + headerkw = {} for lineno, line in lnstream: line = line.rstrip() if line == smaps.SmapsRecorder.SEPSNAPSHOT: if private_only: - snapshots.append(SimpleSnapshot(mappings)) + snapshots.append(SimpleSnapshot(mappings, headerkw)) else: - snapshots.append(Snapshot(mappings)) + snapshots.append(Snapshot(mappings, headerkw)) mappings = [] + headerkw = {} elif line == BenchRunner.SEPBENCH: break else: + if line.startswith(BenchRunner.HEADERSEP): + headerkw.update(parseheader(lnstream)) + continue if private_only: mappings.append(smaps.private(line)) else: @@ -464,16 +479,18 @@ return "private: %d, shared: %d" %(self.private, self.shared) class Snapshot(Mappings): - def __init__(self, mappings): + def __init__(self, mappings, headerkw={}): assert mappings + self.header = headerkw Mappings.__init__(self, mappings) def heap_private(self): return self.filter(group=self.HEAP).private class SimpleSnapshot(object): - def __init__(self, privates): + def __init__(self, privates, headerkw): self.private = sum(privates) + self.header = headerkw # # ============================================================================== Modified: pypy/build/benchmem/testing/test_benchtool.py ============================================================================== --- pypy/build/benchmem/testing/test_benchtool.py (original) +++ pypy/build/benchmem/testing/test_benchtool.py Fri Oct 31 19:11:11 2008 @@ -58,6 +58,7 @@ for name, results in resultset.getname2results(): assert len(results) == 1 assert len(results[0].snapshots) + assert float(results[0].snapshots[0].header['TS']) > 42 def test_pauses(): tmpdir = py.test.ensuretemp("benchrunner") From xoraxax at codespeak.net Fri Oct 31 19:12:39 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 31 Oct 2008 19:12:39 +0100 (CET) Subject: [pypy-svn] r59603 - pypy/build/benchmem Message-ID: <20081031181239.90EC016A38E@codespeak.net> Author: xoraxax Date: Fri Oct 31 19:12:38 2008 New Revision: 59603 Modified: pypy/build/benchmem/report_graphic.py Log: Change graph reporter to use wall clock time instead of %. This is a bit annoying because of different running time but certainly more dependable because we do a lot of IO in the logger and have to expect scheduling issues. Fix graph reporter to check whether the benchlog contains the particular result sets at all. Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Fri Oct 31 19:12:38 2008 @@ -22,7 +22,8 @@ * ip data * private rest """ - + if not results: + return heap_private = numpy.array([result.snapshot.filter(group=HEAP).private for result in results]) ip_code = numpy.array([result.snapshot.filter(group=result.executable, @@ -64,7 +65,8 @@ private memory consumed for object allocation (without base interpreter size) """ - + if not resultset.results: + return def incremental_private(result): return (result.snapshots[1].heap_private() - result.snapshots[0].heap_private()) @@ -118,17 +120,31 @@ pylab.clf() for name, results in resultset.filter(benchtype="appprofiles").getname2results(): plots = [] + USE_TS = True for result in results: - lgt = len(result.snapshots) - x = [(float(i)/lgt)*100 for i in range(lgt)] - y = [snapshot.private - totals[result.executable] + if not USE_TS: + lgt = len(result.snapshots) + x = [(float(i)/lgt)*100 for i in range(lgt)] + else: + x = [float(ss.header['TS']) for ss in result.snapshots] + min_ts = min(x) + x = [val - min_ts for val in x] + if totals: + basesize = totals[result.executable] + else: + basesize = 0 + # XXX measures also the used code pages, this is bad because we do not want to + # mix effects because of code generation and GC behaviour + y = [snapshot.private - basesize for snapshot in result.snapshots] pylab.title(name) plots.append(pylab.plot(x, y)) pylab.legend(plots, [result.executable for result in results]) - pylab.xlabel("time (%)") - pylab.ylabel("incremental private memory consumption") + xlabel = ["time (%)", "wall clock time (s)"][USE_TS] + pylab.xlabel(xlabel) + ylabel = ["", "incremental "][bool(basesize)] + "private memory consumption" + pylab.ylabel(ylabel) pylab.savefig(BASE + 'appprofiles_%s.ps' % name) if SHOW: pylab.show() From xoraxax at codespeak.net Fri Oct 31 19:36:19 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 31 Oct 2008 19:36:19 +0100 (CET) Subject: [pypy-svn] r59604 - pypy/build/benchmem Message-ID: <20081031183619.B8C6416A3F5@codespeak.net> Author: xoraxax Date: Fri Oct 31 19:36:18 2008 New Revision: 59604 Modified: pypy/build/benchmem/report_graphic.py Log: Revert last checkin on graph reporter to ease merging. Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Fri Oct 31 19:36:18 2008 @@ -22,8 +22,7 @@ * ip data * private rest """ - if not results: - return + heap_private = numpy.array([result.snapshot.filter(group=HEAP).private for result in results]) ip_code = numpy.array([result.snapshot.filter(group=result.executable, @@ -65,8 +64,7 @@ private memory consumed for object allocation (without base interpreter size) """ - if not resultset.results: - return + def incremental_private(result): return (result.snapshots[1].heap_private() - result.snapshots[0].heap_private()) @@ -120,31 +118,17 @@ pylab.clf() for name, results in resultset.filter(benchtype="appprofiles").getname2results(): plots = [] - USE_TS = True for result in results: - if not USE_TS: - lgt = len(result.snapshots) - x = [(float(i)/lgt)*100 for i in range(lgt)] - else: - x = [float(ss.header['TS']) for ss in result.snapshots] - min_ts = min(x) - x = [val - min_ts for val in x] - if totals: - basesize = totals[result.executable] - else: - basesize = 0 - # XXX measures also the used code pages, this is bad because we do not want to - # mix effects because of code generation and GC behaviour - y = [snapshot.private - basesize + lgt = len(result.snapshots) + x = [(float(i)/lgt)*100 for i in range(lgt)] + y = [snapshot.private - totals[result.executable] for snapshot in result.snapshots] pylab.title(name) plots.append(pylab.plot(x, y)) pylab.legend(plots, [result.executable for result in results]) - xlabel = ["time (%)", "wall clock time (s)"][USE_TS] - pylab.xlabel(xlabel) - ylabel = ["", "incremental "][bool(basesize)] + "private memory consumption" - pylab.ylabel(ylabel) + pylab.xlabel("time (%)") + pylab.ylabel("incremental private memory consumption") pylab.savefig(BASE + 'appprofiles_%s.ps' % name) if SHOW: pylab.show() From fijal at codespeak.net Fri Oct 31 20:18:52 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 31 Oct 2008 20:18:52 +0100 (CET) Subject: [pypy-svn] r59605 - pypy/build/benchmem Message-ID: <20081031191852.3C8F816A36C@codespeak.net> Author: fijal Date: Fri Oct 31 20:18:50 2008 New Revision: 59605 Added: pypy/build/benchmem/smaps_monitor.py (contents, props changed) Log: simple yet usefull tool Added: pypy/build/benchmem/smaps_monitor.py ============================================================================== --- (empty file) +++ pypy/build/benchmem/smaps_monitor.py Fri Oct 31 20:18:50 2008 @@ -0,0 +1,28 @@ +#!/usr/bin/env python +""" Usage: smaps_monitor pid + +Where pid is a process id of monitored process +""" + +import sys, time +import py + +def main(pid): + from smaps import SmapsRecorder + sm = SmapsRecorder(pid, None) + + while 1: + l = [] + try: + sm.snapshot(lambda self, a, b: l.append(a), lambda self : None) + except py.error.ENOENT: + break + print sum([i[4] + i[5] for i in l]) + time.sleep(1) + +if __name__ == '__main__': + if len(sys.argv) != 2: + print __doc__ + sys.exit() + pid = int(sys.argv[1]) + main(pid) From fijal at codespeak.net Fri Oct 31 20:19:18 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 31 Oct 2008 20:19:18 +0100 (CET) Subject: [pypy-svn] r59606 - in pypy/build/benchmem: . testing Message-ID: <20081031191918.1F0CB16A371@codespeak.net> Author: fijal Date: Fri Oct 31 20:19:17 2008 New Revision: 59606 Added: pypy/build/benchmem/testing/conftest.py (contents, props changed) pypy/build/benchmem/testing/test_report_graph.py (contents, props changed) Modified: pypy/build/benchmem/report_graphic.py Log: A bit of progress - now report_graphic is nicely tested Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Fri Oct 31 20:19:17 2008 @@ -10,10 +10,101 @@ HEAP = runbench.Mappings.HEAP CODE = runbench.Mappings.CODE DATA = runbench.Mappings.DATA -BASE = '' -SHOW = False +SPLIT = 10 -def process_baseint_sizes(results): +class Plotter(object): + def __init__(self, basepath='', show=False): + self.basepath = basepath + self.show = show + + def plot_baseint_sizes(self, heap_private, ip_code, ip_data, rest, results): + # XXX add axes scaling + heap_private = numpy.array(heap_private) + ip_code = numpy.array(ip_code) + ip_data = numpy.array(ip_data) + rest = numpy.array(rest) + pylab.clf() + WIDTH = .1 + lgt = len(results) + ind = numpy.array([float(i)/lgt for i in range(lgt)]) + p0 = pylab.bar(ind, heap_private, WIDTH, color='r') + p1 = pylab.bar(ind, ip_code, WIDTH, color='b', bottom=heap_private) + p2 = pylab.bar(ind, ip_data, WIDTH, color='w', bottom=heap_private+ip_code) + p3 = pylab.bar(ind, rest, WIDTH, color='black', + bottom=heap_private+ip_code+ip_data) + pylab.xticks(ind + WIDTH/2, [result.executable for result in results]) + pylab.legend([p0[0], p1[0], p2[0], p3[0]], + ['heap private', 'ip code', 'ip data', 'rest']) + pylab.ylabel('memory consumption (kB)') + if self.basepath is not None: + pylab.savefig(self.basepath + "base_size.ps") + if self.show: + pylab.show() + res = {} + for i, value in enumerate(ip_code + ip_data + heap_private + rest): + res[results[i].executable] = value + return res + + def plot_objsizes(self, benchresults, names, executables, split=SPLIT): + # XXX implement saner colorization + colors = ['r', 'g', 'b', 'black', 'white', 'cyan', 'magenta', 'yellow' + 'purple', 'grey'] + + benchresults = numpy.array(benchresults) + names = numpy.array(names) + end = len(benchresults[0])//split + if len(benchresults[0]) % split != 0: + end += 1 + + for view in range(end): + start = view * split + end = min((view + 1)*split, len(benchresults[0])) + results = benchresults[:, start:end] + pylab.clf() + lgt = len(results[0]) + baseindices = numpy.array([float(i)/lgt for i in range(lgt)]) + basewidth = (baseindices[1] - baseindices[0]) + skip = (basewidth * .5) / len(benchresults) + bars = [] + for i, benchresult in enumerate(results): + bars.append(pylab.bar(baseindices + skip * i, benchresult, skip, + color=colors[i])) + pylab.legend([bar[0] for bar in bars], executables) + # XXX a lot of magic is required to provide a reasonable + # set of non-overlapping xticks + pylab.xticks(baseindices + basewidth/4, ['B%d' % i for i in + range(start, end)]) + pylab.ylabel("memory consumption (kB)") + if self.basepath is not None: + pylab.savefig(self.basepath + "objsizes_%d.ps" % view) + if self.show: + pylab.show() + + def plot_appprofiles(self, name2results, totals): + """ This function plots incremental memory consumption of app benchmarks + (withou interpreter size) versus time (in %s) + """ + + for name, results in name2results: + pylab.clf() + plots = [] + for result in results: + lgt = len(result.snapshots) + x = [(float(i)/lgt)*100 for i in range(lgt)] + y = [snapshot.private - totals[result.executable] + for snapshot in result.snapshots] + pylab.title(name) + plots.append(pylab.plot(x, y)) + + pylab.legend(plots, [result.executable for result in results]) + pylab.xlabel("time (%)") + pylab.ylabel("incremental private memory consumption (kB)") + if self.basepath is not None: + pylab.savefig(BASE + 'appprofiles_%s.ps' % name) + if self.show: + pylab.show() + +def process_baseint_sizes(results, plotter): """ This function plots base interpreter sizes of various interpreters with bars specifying: @@ -35,31 +126,9 @@ inv=True). filter(group=HEAP, inv=True).private for result in results]) - return plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results) - -def plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results): - # XXX add axes scaling - pylab.clf() - WIDTH = .1 - lgt = len(results) - ind = numpy.array([float(i)/lgt for i in range(lgt)]) - p0 = pylab.bar(ind, heap_private, WIDTH, color='r') - p1 = pylab.bar(ind, ip_code, WIDTH, color='b', bottom=heap_private) - p2 = pylab.bar(ind, ip_data, WIDTH, color='w', bottom=heap_private+ip_code) - p3 = pylab.bar(ind, rest, WIDTH, color='black', - bottom=heap_private+ip_code+ip_data) - pylab.xticks(ind + WIDTH/2, [result.executable for result in results]) - pylab.legend([p0[0], p1[0], p2[0], p3[0]], - ['heap private', 'ip code', 'ip data', 'rest']) - pylab.savefig(BASE + "base_size.ps") - if SHOW: - pylab.show() - res = {} - for i, value in enumerate(ip_code + ip_data + heap_private + rest): - res[results[i].executable] = value - return res + return plotter.plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results) -def process_objsizes(resultset): +def process_objsizes(resultset, plotter): """ This function creates series of graphs for showing incremental private memory consumed for object allocation (without base interpreter size) @@ -76,72 +145,19 @@ for _, results in results: for i, result in enumerate(results): benchresults[i].append(incremental_private(result)) - plot_objsizes(benchresults, names, executables) + plotter.plot_objsizes(benchresults, names, executables) -def plot_objsizes(benchresults, names, executables): - # XXX implement saner colorization - colors = ['r', 'g', 'b', 'black', 'white', 'cyan', 'magenta', 'yellow' - 'purple', 'grey'] - - benchresults = numpy.array(benchresults) - names = numpy.array(names) - - split = 10 # max number of bars per graph - for view in range(len(benchresults[0])/split): - start = view * split - end = min((view + 1)*split, len(benchresults[0])) - results = benchresults[:, start:end] - pylab.clf() - lgt = len(results[0]) - baseindices = numpy.array([float(i)/lgt for i in range(lgt)]) - basewidth = (baseindices[1] - baseindices[0]) - skip = (basewidth * .5) / len(benchresults) - bars = [] - for i, benchresult in enumerate(results): - bars.append(pylab.bar(baseindices + skip * i, benchresult, skip, - color=colors[i])) - pylab.legend([bar[0] for bar in bars], executables) - # XXX a lot of magic is required to provide a reasonable - # set of non-overlapping xticks - pylab.xticks(baseindices + basewidth/4, ['B%d' % i for i in - range(start, end)]) - pylab.savefig(BASE + "objsizes_%d.ps" % view) - if SHOW: - pylab.show() - -def process_appprofiles(resultset, totals): - """ This function plots incremental memory consumption of app benchmarks - (withou interpreter size) versus time (in %s) - """ - - pylab.clf() - for name, results in resultset.filter(benchtype="appprofiles").getname2results(): - plots = [] - for result in results: - lgt = len(result.snapshots) - x = [(float(i)/lgt)*100 for i in range(lgt)] - y = [snapshot.private - totals[result.executable] - for snapshot in result.snapshots] - pylab.title(name) - plots.append(pylab.plot(x, y)) - - pylab.legend(plots, [result.executable for result in results]) - pylab.xlabel("time (%)") - pylab.ylabel("incremental private memory consumption") - pylab.savefig(BASE + 'appprofiles_%s.ps' % name) - if SHOW: - pylab.show() - def main(filename): + plotter = Plotter() resultset = runbench.ResultSet() resultset.parse(py.path.local(filename)) totals = process_baseint_sizes(resultset.filter(benchtype="basesize"). - results) - process_objsizes(resultset.filter(benchtype="objsizes")) - process_appprofiles(resultset.filter(benchtype="appprofiles"), - totals) + results, plotter) + process_objsizes(resultset.filter(benchtype="objsizes"), plotter) + plotter.plot_appprofiles(resultset.filter(benchtype="appprofiles"), + totals) if __name__ == '__main__': if len(sys.argv) > 3: Added: pypy/build/benchmem/testing/conftest.py ============================================================================== --- (empty file) +++ pypy/build/benchmem/testing/conftest.py Fri Oct 31 20:19:17 2008 @@ -0,0 +1,8 @@ + +import py + +Option = py.test.config.Option +option = py.test.config.addoptions("dotviewer options", + Option('--view', action="store_true", dest="view", default=False, + help="allow interactive tests"), + ) Added: pypy/build/benchmem/testing/test_report_graph.py ============================================================================== --- (empty file) +++ pypy/build/benchmem/testing/test_report_graph.py Fri Oct 31 20:19:17 2008 @@ -0,0 +1,42 @@ + +import py, os +from report_graphic import Plotter + +class MockResult(object): + def __init__(self, executable, snapshots=[]): + self.executable = executable + self.snapshots = snapshots + +class MockSnapshot(object): + def __init__(self, private): + self.private = private + +class TestPlotter(object): + def setup_class(cls): + if py.test.config.option.view: + cls.plotter = Plotter(None, True) + else: + tmpdir = py.test.ensuretemp('plotter') + cls.plotter = Plotter(str(tmpdir) + os.path.sep) + cls.results = [MockResult('py1'), MockResult('py2')] + + def test_baseint_sizes(self): + # this should show two equal bars, with different colors inside + self.plotter.plot_baseint_sizes([1, 0], [1, 1], [1, 2], [1, 1], + self.results) + + def test_objsizes(self): + bars = [[1, 2, 3, 4, 5, 6], [2, 4, 6, 8, 10, 12]] + names = ['B%d' for i in range(6)] + # this should show two graphs full of bars, where one is 2x other + self.plotter.plot_objsizes(bars, names, ['py1', 'py2'], 4) + + def test_appprofiles(self): + def new_snapshots(*lst): + return [MockSnapshot(i) for i in lst] + + results = [MockResult('py1', new_snapshots(1, 2, 3, 4, 5, 6, 7)), + MockResult('py2', new_snapshots(7, 6, 5, 4, 3, 2, 1))] + name2results = [('bench1', results), ('bench2', results)] + # this one should show two identical graphs of shape of X + self.plotter.plot_appprofiles(name2results, {'py1': 1, 'py2': 0}) From xoraxax at codespeak.net Fri Oct 31 20:45:13 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 31 Oct 2008 20:45:13 +0100 (CET) Subject: [pypy-svn] r59607 - pypy/build/benchmem Message-ID: <20081031194513.2C77A16A2E1@codespeak.net> Author: xoraxax Date: Fri Oct 31 20:45:11 2008 New Revision: 59607 Modified: pypy/build/benchmem/report_graphic.py Log: Readded timestamp usage, fix bug when certain benchtypes are not available. Now the timestamps are used to deskew the sampling results. Now only the scheduler influences on the main process remain. Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Fri Oct 31 20:45:11 2008 @@ -82,25 +82,39 @@ def plot_appprofiles(self, name2results, totals): """ This function plots incremental memory consumption of app benchmarks - (withou interpreter size) versus time (in %s) + (without interpreter size if possible) versus time """ + SHOW_TS = False for name, results in name2results: pylab.clf() plots = [] for result in results: - lgt = len(result.snapshots) - x = [(float(i)/lgt)*100 for i in range(lgt)] - y = [snapshot.private - totals[result.executable] + timestamps = [float(ss.header['TS']) for ss in result.snapshots] + min_ts, max_ts = min(timestamps), max(timestamps) + d_ts = max_ts - min_ts + if SHOW_TS: + x = [val - min_ts for val in timestamps] + else: + x = [(val - min_ts)/d_ts*100 for val in timestamps] + if totals: + basesize = totals[result.executable] + else: + basesize = 0 + # XXX measures also the used code pages, this is bad because we do not want to + # mix effects because of code generation and GC behaviour + y = [snapshot.private - basesize for snapshot in result.snapshots] pylab.title(name) plots.append(pylab.plot(x, y)) pylab.legend(plots, [result.executable for result in results]) - pylab.xlabel("time (%)") - pylab.ylabel("incremental private memory consumption (kB)") + xlabel = ["wall clock time (%)", "wall clock time (s)"][SHOW_TS] + pylab.xlabel(xlabel) + ylabel = ["", "incremental "][bool(basesize)] + "private memory consumption (kB)" + pylab.ylabel(ylabel) if self.basepath is not None: - pylab.savefig(BASE + 'appprofiles_%s.ps' % name) + pylab.savefig(self.basepath + 'appprofiles_%s.ps' % name) if self.show: pylab.show() @@ -113,7 +127,8 @@ * ip data * private rest """ - + if not results: + return heap_private = numpy.array([result.snapshot.filter(group=HEAP).private for result in results]) ip_code = numpy.array([result.snapshot.filter(group=result.executable, @@ -133,7 +148,8 @@ private memory consumed for object allocation (without base interpreter size) """ - + if not resultset.results: + return def incremental_private(result): return (result.snapshots[1].heap_private() - result.snapshots[0].heap_private()) @@ -156,7 +172,7 @@ totals = process_baseint_sizes(resultset.filter(benchtype="basesize"). results, plotter) process_objsizes(resultset.filter(benchtype="objsizes"), plotter) - plotter.plot_appprofiles(resultset.filter(benchtype="appprofiles"), + plotter.plot_appprofiles(resultset.filter(benchtype="appprofiles").getname2results(), totals) if __name__ == '__main__': From fijal at codespeak.net Fri Oct 31 20:48:46 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 31 Oct 2008 20:48:46 +0100 (CET) Subject: [pypy-svn] r59608 - pypy/build/benchmem Message-ID: <20081031194846.A3AC416A348@codespeak.net> Author: fijal Date: Fri Oct 31 20:48:46 2008 New Revision: 59608 Modified: pypy/build/benchmem/report_graphic.py Log: kill this, not to confuse people. This stuff goes to report.py Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Fri Oct 31 20:48:46 2008 @@ -162,25 +162,3 @@ for i, result in enumerate(results): benchresults[i].append(incremental_private(result)) plotter.plot_objsizes(benchresults, names, executables) - - - -def main(filename): - plotter = Plotter() - resultset = runbench.ResultSet() - resultset.parse(py.path.local(filename)) - totals = process_baseint_sizes(resultset.filter(benchtype="basesize"). - results, plotter) - process_objsizes(resultset.filter(benchtype="objsizes"), plotter) - plotter.plot_appprofiles(resultset.filter(benchtype="appprofiles").getname2results(), - totals) - -if __name__ == '__main__': - if len(sys.argv) > 3: - print >>sys.stderr, __doc__ - sys.exit(1) - if len(sys.argv) == 2: - name = sys.argv[1] - else: - name = 'bench.log' - main(name) From fijal at codespeak.net Fri Oct 31 21:13:54 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 31 Oct 2008 21:13:54 +0100 (CET) Subject: [pypy-svn] r59609 - pypy/build/benchmem Message-ID: <20081031201354.95FB216A150@codespeak.net> Author: fijal Date: Fri Oct 31 21:13:52 2008 New Revision: 59609 Modified: pypy/build/benchmem/report.py pypy/build/benchmem/report_graphic.py Log: move main to report.py Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Fri Oct 31 21:13:52 2008 @@ -7,11 +7,15 @@ """ import py, os -import smaps, runbench +import smaps, runbench, numpy parser = py.compat.optparse.OptionParser(usage=__doc__) parser.add_option("-l", "--benchlog", action="store", dest="benchlog", default="bench.log", help="logfile to read results from") +parser.add_option("-g", "--store-graphs", action="store", dest="basepath", + default="", help="optional path to store picture output") +parser.add_option("-t", "--no-text", action="store_true", dest="notext", + help="disable text reporting") def asciitable(table): colmax = [] @@ -72,39 +76,6 @@ self.tw.sep("=", "private RSS at checkpoints: %s" %(name,)) self.tw.line(asciitable(rows)) -class Gnuplot(TableReporter): - def begin(self): - self.output = [] - self.pythons = [] - - def report(self, name, rows): - if not self.pythons: - self.pythons.extend(rows[0][1:]) - self.output.append(rows[2][1:]) - - def end(self): - pythons = self.pythons - output = self.output - - runbench.mydir.join("gnuplotdata").write( - "\n".join([" ".join([str(j) for j in i]) for i in output])) - - def new_cmd(num, name): - s = ("plot 'gnuplotdata' using ($%d) with histograms title '%s'" % - (num + 1,name)) - if num > 0: - s = "re" + s - return s - - plotcmds = "\n".join([new_cmd(i, name) for i, name in enumerate(pythons)]) - runbench.mydir.join("gnuplotcmd").write( - """set terminal postscript color - set output 'output.ps' - %s - """ % plotcmds - ) - os.system("gnuplot gnuplotcmd") - class IncrementalSizePerBench: def __init__(self, resultset): self.resultset = resultset.filter(benchtype="objsizes") @@ -143,6 +114,23 @@ #row.append(incsize) rows.append(row) tw.line(asciitable(rows)) + + def run_graphic(self, plotter): + """ This function creates series of graphs for showing incremental + private memory consumed for object allocation (without base interpreter + size) + """ + resultset = self.resultset + if not resultset.results: + return + names = [name for name, _ in resultset.getname2results()] + results = resultset.getname2results() + benchresults = [[] for _ in range(len(results[0]))] + executables = [result.executable for result in results[0][1]] + for _, results in results: + for i, result in enumerate(results): + benchresults[i].append(self.get_incremental_size(result)) + plotter.plot_objsizes(benchresults, names, executables) def get_incremental_size(self, result): # checkpoint 0: state before benchmark @@ -153,6 +141,9 @@ return inbench - basesize class BaseSizeOfInterpreters: + HEAP = runbench.Mappings.HEAP + CODE = runbench.Mappings.CODE + DATA = runbench.Mappings.DATA def __init__(self, resultset): self.resultset = resultset.filter(benchtype="basesize") @@ -174,44 +165,68 @@ for result in results: row.append(mapping_func(result)) rows.append(row) - HEAP = runbench.Mappings.HEAP - CODE = runbench.Mappings.CODE - DATA = runbench.Mappings.DATA makerow("HEAP-RSS", lambda result: - result.snapshot.filter(group=HEAP).rss) + result.snapshot.filter(group=self.HEAP).rss) makerow("HEAP-private_clean", lambda result: - result.snapshot.filter(group=HEAP).private_clean) + result.snapshot.filter(group=self.HEAP).private_clean) makerow("HEAP-private_dirty", lambda result: - result.snapshot.filter(group=HEAP).private_dirty) + result.snapshot.filter(group=self.HEAP).private_dirty) # we only show the clean bits of the code, this might not really work # out if the code is not compiled position-indepently, likewise the often # seen dirty code page might be a dispatch table (correct term?) of the linker makerow("IP-CODE-shared_clean", lambda result: - result.snapshot.filter(group=result.executable, kind=CODE).shared_clean) + result.snapshot.filter(group=result.executable, kind=self.CODE).shared_clean) makerow("IP-CODE-private_clean", lambda result: - result.snapshot.filter(group=result.executable, kind=CODE).private_clean) + result.snapshot.filter(group=result.executable, kind=self.CODE).private_clean) # whole static data of the process in memory, also including e.g. shared data with other processes makerow("IP-DATA-RSS", lambda result: - result.snapshot.filter(group=result.executable, kind=DATA).rss) + result.snapshot.filter(group=result.executable, kind=self.DATA).rss) # static data that is not shared with another process and was not modified by the process # can be easily shared with another process makerow("IP-DATA-private_clean", lambda result: - result.snapshot.filter(group=result.executable, kind=DATA).private_clean) + result.snapshot.filter(group=result.executable, kind=self.DATA).private_clean) # static data that is not shared with another process and was modified by the process makerow("IP-DATA-private_dirty", lambda result: - result.snapshot.filter(group=result.executable, kind=DATA).private_dirty) + result.snapshot.filter(group=result.executable, kind=self.DATA).private_dirty) # rest includes other shared libraries that are neither the interpreter nor the heap makerow("REST-private_clean", lambda result: result.snapshot.filter(group=result.executable, inv=True). - filter(group=HEAP, inv=True).private_clean) + filter(group=self.HEAP, inv=True).private_clean) makerow("REST-private_dirty", lambda result: result.snapshot.filter(group=result.executable, inv=True). - filter(group=HEAP, inv=True).private_dirty) + filter(group=self.HEAP, inv=True).private_dirty) makerow("REST-RSS", lambda result: result.snapshot.filter(group=result.executable, inv=True). - filter(group=HEAP, inv=True).rss) + filter(group=self.HEAP, inv=True).rss) tw.line(asciitable(rows)) + def run_graphic(self, plotter): + """ This function plots base interpreter sizes of various interpreters + with bars specifying: + + * heap private + * ip code + * ip data + * private rest + """ + results = self.resultset.results + if not results: + return + heap_private = numpy.array([result.snapshot.filter(group=self.HEAP).private + for result in results]) + ip_code = numpy.array([result.snapshot.filter(group=result.executable, + kind=self.CODE). + private for result in results]) + ip_data = numpy.array([result.snapshot.filter(group=result.executable, + kind=self.DATA). + private for result in results]) + rest = numpy.array([result.snapshot.filter(group=result.executable, + inv=True). + filter(group=self.HEAP, inv=True).private for result in + results]) + return plotter.plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results) + + class BaseTimeOfInterpreters: def __init__(self, resultset): self.resultset = resultset.filter(benchtype="basetime") @@ -237,6 +252,13 @@ timing['real'], timing['user'], timing['sys']]) tw.line(asciitable(rows)) +class AppProfiles(object): + def __init__(self, resultset): + self.name2result = resultset.filter(benchtype="appprofiles").getname2results() + + def run_graphic(self, plotter, totals): + plotter.plot_appprofiles(self.name2result, totals) + if __name__ == "__main__": options, args = parser.parse_args() @@ -245,10 +267,19 @@ resultset.parse(benchlog) #maxtable_overview(reader) - CheckpointDetails(resultset).run() - IncrementalSizePerBench(resultset).run() - BaseSizeOfInterpreters(resultset).run() - BaseTimeOfInterpreters(resultset).run() + if not options.notext: + CheckpointDetails(resultset).run() + IncrementalSizePerBench(resultset).run() + BaseSizeOfInterpreters(resultset).run() + BaseTimeOfInterpreters(resultset).run() + + if options.basepath: + from report_graphic import Plotter + plotter = Plotter(options.basepath) + #plotter = Plotter(None, True) + IncrementalSizePerBench(resultset).run_graphic(plotter) + totals = BaseSizeOfInterpreters(resultset).run_graphic(plotter) + AppProfiles(resultset).run_graphic(plotter, totals) #for name, results in reader.name2results.items(): # tw.sep("=", name) Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Fri Oct 31 21:13:52 2008 @@ -117,48 +117,3 @@ pylab.savefig(self.basepath + 'appprofiles_%s.ps' % name) if self.show: pylab.show() - -def process_baseint_sizes(results, plotter): - """ This function plots base interpreter sizes of various interpreters - with bars specifying: - - * heap private - * ip code - * ip data - * private rest - """ - if not results: - return - heap_private = numpy.array([result.snapshot.filter(group=HEAP).private - for result in results]) - ip_code = numpy.array([result.snapshot.filter(group=result.executable, - kind=CODE). - private for result in results]) - ip_data = numpy.array([result.snapshot.filter(group=result.executable, - kind=DATA). - private for result in results]) - rest = numpy.array([result.snapshot.filter(group=result.executable, - inv=True). - filter(group=HEAP, inv=True).private for result in - results]) - return plotter.plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results) - -def process_objsizes(resultset, plotter): - """ This function creates series of graphs for showing incremental - private memory consumed for object allocation (without base interpreter - size) - """ - if not resultset.results: - return - def incremental_private(result): - return (result.snapshots[1].heap_private() - - result.snapshots[0].heap_private()) - - names = [name for name, _ in resultset.getname2results()] - results = resultset.getname2results() - benchresults = [[] for _ in range(len(results[0]))] - executables = [result.executable for result in results[0][1]] - for _, results in results: - for i, result in enumerate(results): - benchresults[i].append(incremental_private(result)) - plotter.plot_objsizes(benchresults, names, executables) From xoraxax at codespeak.net Fri Oct 31 21:35:12 2008 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 31 Oct 2008 21:35:12 +0100 (CET) Subject: [pypy-svn] r59610 - pypy/build/benchmem Message-ID: <20081031203512.29A8416A184@codespeak.net> Author: xoraxax Date: Fri Oct 31 21:35:10 2008 New Revision: 59610 Modified: pypy/build/benchmem/report.py pypy/build/benchmem/report_graphic.py Log: Show heap private memory for approfiles, this excludes dirty static data, though. Modified: pypy/build/benchmem/report.py ============================================================================== --- pypy/build/benchmem/report.py (original) +++ pypy/build/benchmem/report.py Fri Oct 31 21:35:10 2008 @@ -224,7 +224,8 @@ inv=True). filter(group=self.HEAP, inv=True).private for result in results]) - return plotter.plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results) + plotter.plot_baseint_sizes(heap_private, ip_code, ip_data, rest, [r.executable for r in results]) + return dict([(r.executable, r.snapshot.heap_private()) for r in results]) class BaseTimeOfInterpreters: Modified: pypy/build/benchmem/report_graphic.py ============================================================================== --- pypy/build/benchmem/report_graphic.py (original) +++ pypy/build/benchmem/report_graphic.py Fri Oct 31 21:35:10 2008 @@ -17,7 +17,7 @@ self.basepath = basepath self.show = show - def plot_baseint_sizes(self, heap_private, ip_code, ip_data, rest, results): + def plot_baseint_sizes(self, heap_private, ip_code, ip_data, rest, executables): # XXX add axes scaling heap_private = numpy.array(heap_private) ip_code = numpy.array(ip_code) @@ -32,7 +32,7 @@ p2 = pylab.bar(ind, ip_data, WIDTH, color='w', bottom=heap_private+ip_code) p3 = pylab.bar(ind, rest, WIDTH, color='black', bottom=heap_private+ip_code+ip_data) - pylab.xticks(ind + WIDTH/2, [result.executable for result in results]) + pylab.xticks(ind + WIDTH/2, executables) pylab.legend([p0[0], p1[0], p2[0], p3[0]], ['heap private', 'ip code', 'ip data', 'rest']) pylab.ylabel('memory consumption (kB)') @@ -40,10 +40,6 @@ pylab.savefig(self.basepath + "base_size.ps") if self.show: pylab.show() - res = {} - for i, value in enumerate(ip_code + ip_data + heap_private + rest): - res[results[i].executable] = value - return res def plot_objsizes(self, benchresults, names, executables, split=SPLIT): # XXX implement saner colorization @@ -80,7 +76,7 @@ if self.show: pylab.show() - def plot_appprofiles(self, name2results, totals): + def plot_appprofiles(self, name2results, base_snapshots): """ This function plots incremental memory consumption of app benchmarks (without interpreter size if possible) versus time """ @@ -97,13 +93,12 @@ x = [val - min_ts for val in timestamps] else: x = [(val - min_ts)/d_ts*100 for val in timestamps] - if totals: - basesize = totals[result.executable] + if base_snapshots: + basesize = base_snapshots[result.executable].heap_private() else: basesize = 0 - # XXX measures also the used code pages, this is bad because we do not want to - # mix effects because of code generation and GC behaviour - y = [snapshot.private - basesize + y = [snapshot.heap_private() - basesize + # we do not measure the dirty static data here which is probably sane for snapshot in result.snapshots] pylab.title(name) plots.append(pylab.plot(x, y)) @@ -111,9 +106,10 @@ pylab.legend(plots, [result.executable for result in results]) xlabel = ["wall clock time (%)", "wall clock time (s)"][SHOW_TS] pylab.xlabel(xlabel) - ylabel = ["", "incremental "][bool(basesize)] + "private memory consumption (kB)" + ylabel = ["", "incremental "][bool(basesize)] + "heap memory consumption (kB)" pylab.ylabel(ylabel) if self.basepath is not None: pylab.savefig(self.basepath + 'appprofiles_%s.ps' % name) if self.show: pylab.show() + From fijal at codespeak.net Fri Oct 31 22:52:27 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 31 Oct 2008 22:52:27 +0100 (CET) Subject: [pypy-svn] r59611 - pypy/trunk/lib-python Message-ID: <20081031215227.E125416A38A@codespeak.net> Author: fijal Date: Fri Oct 31 22:52:25 2008 New Revision: 59611 Modified: pypy/trunk/lib-python/conftest.py Log: these are supported now Modified: pypy/trunk/lib-python/conftest.py ============================================================================== --- pypy/trunk/lib-python/conftest.py (original) +++ pypy/trunk/lib-python/conftest.py Fri Oct 31 22:52:25 2008 @@ -243,7 +243,7 @@ RegrTest('test_glob.py', core=True), RegrTest('test_global.py', core=True), RegrTest('test_grammar.py', core=True), - RegrTest('test_grp.py', skip="unsupported extension module"), + RegrTest('test_grp.py'), RegrTest('test_gzip.py'), RegrTest('test_hash.py', core=True), @@ -331,7 +331,7 @@ RegrTest('test_profile.py'), RegrTest('test_profilehooks.py', core=True), RegrTest('test_pty.py', skip="unsupported extension module"), - RegrTest('test_pwd.py', skip="unsupported extension module"), + RegrTest('test_pwd.py'), RegrTest('test_pyclbr.py'), RegrTest('test_pyexpat.py'), From fijal at codespeak.net Fri Oct 31 23:18:38 2008 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 31 Oct 2008 23:18:38 +0100 (CET) Subject: [pypy-svn] r59612 - pypy/trunk/pypy/lib Message-ID: <20081031221838.E0BCE16A2E8@codespeak.net> Author: fijal Date: Fri Oct 31 23:18:38 2008 New Revision: 59612 Added: pypy/trunk/pypy/lib/grp.py (contents, props changed) Log: add a grp module Added: pypy/trunk/pypy/lib/grp.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/lib/grp.py Fri Oct 31 23:18:38 2008 @@ -0,0 +1,84 @@ + +""" This module provides ctypes version of cpython's grp module +""" + +from ctypes import Structure, c_char_p, c_int, POINTER +from ctypes_support import standard_c_lib as libc + +gid_t = c_int + +class GroupStruct(Structure): + _fields_ = ( + ('gr_name', c_char_p), + ('gr_passwd', c_char_p), + ('gr_gid', gid_t), + ('gr_mem', POINTER(c_char_p)), + ) + +class Group(object): + def __init__(self, gr_name, gr_passwd, gr_gid, gr_mem): + self.gr_name = gr_name + self.gr_passwd = gr_passwd + self.gr_gid = gr_gid + self.gr_mem = gr_mem + + def __getitem__(self, item): + if item == 0: + return self.gr_name + elif item == 1: + return self.gr_passwd + elif item == 2: + return self.gr_gid + elif item == 3: + return self.gr_mem + else: + raise IndexError(item) + + def __len__(self): + return 4 + + def __repr__(self): + return str((self.gr_name, self.gr_passwd, self.gr_gid, self.gr_mem)) + + # whatever else... + +libc.getgrgid.argtypes = [gid_t] +libc.getgrgid.restype = POINTER(GroupStruct) + +libc.getgrnam.argtypes = [c_char_p] +libc.getgrnam.restype = POINTER(GroupStruct) + +libc.getgrent.argtypes = [] +libc.getgrent.restype = POINTER(GroupStruct) + +def _group_from_gstruct(res): + i = 0 + mem = [] + while res.contents.gr_mem[i]: + mem.append(res.contents.gr_mem[i]) + i += 1 + return Group(res.contents.gr_name, res.contents.gr_passwd, + res.contents.gr_gid, mem) + +def getgrgid(gid): + res = libc.getgrgid(gid) + if not res: + # XXX maybe check error eventually + raise KeyError(gid) + return _group_from_gstruct(res) + +def getgrnam(gid): + res = libc.getgrnam(gid) + if not res: + raise KeyError(gid) + return _group_from_gstruct(res) + +def getgrall(): + libc.setgrent() + lst = [] + while 1: + p = libc.getgrent() + if not p: + libc.endgrent() + return lst + lst.append(_group_from_gstruct(p))